IOMX: separate node interface from IOMX

- Separate node interface from IOMX. Client allocates the
  node through IOMX, and once it has the node interface,
  it can interact with the node directly. There is no need
  to go through IOMX and refer to the node by id.

- Simplify OMX, remove id-to-instance mapping on server
  side, and move the callback dispatch into node instance
  (as dispatcher is per-node).

- Keep track of node generation on client side to ensure
  that message handling ignores messages directed at an
  expired node.

- Remove MuxOMX, always use IOMX from media.codec.

- Minor whitespace reformatting.

bug: 31399200

Change-Id: I8aef6ec1fa5aba861da7d121960ed2974a963d81
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index c0c48c1..f413fd7 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -36,6 +36,7 @@
 
 class IGraphicBufferSource;
 class IMemory;
+class IOMXNode;
 class IOMXObserver;
 class NativeHandle;
 struct omx_message;
@@ -45,12 +46,14 @@
     DECLARE_META_INTERFACE(OMX);
 
     typedef uint32_t buffer_id;
-    typedef uint32_t node_id;
 
-    // Given a node_id and the calling process' pid, returns true iff
-    // the implementation of the OMX interface lives in the same
-    // process.
-    virtual bool livesLocally(node_id node, pid_t pid) = 0;
+    enum {
+        kFenceTimeoutMs = 1000
+    };
+
+    // Returns true iff the implementation of the OMX interface
+    // lives in the same process.
+    virtual bool livesLocally() = 0;
 
     struct ComponentInfo {
         String8 mName;
@@ -60,85 +63,86 @@
 
     virtual status_t allocateNode(
             const char *name, const sp<IOMXObserver> &observer,
-            sp<IBinder> *nodeBinder,
-            node_id *node) = 0;
+            sp<IBinder> *nodeBinder, sp<IOMXNode> *omxNode) = 0;
 
-    virtual status_t freeNode(node_id node) = 0;
+    virtual status_t createPersistentInputSurface(
+            sp<IGraphicBufferProducer> *bufferProducer,
+            sp<IGraphicBufferConsumer> *bufferConsumer) = 0;
+};
+
+class IOMXNode : public IInterface {
+public:
+    DECLARE_META_INTERFACE(OMXNode);
+
+    typedef IOMX::buffer_id buffer_id;
+
+    virtual status_t freeNode() = 0;
 
     virtual status_t sendCommand(
-            node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) = 0;
+            OMX_COMMANDTYPE cmd, OMX_S32 param) = 0;
 
     virtual status_t getParameter(
-            node_id node, OMX_INDEXTYPE index,
-            void *params, size_t size) = 0;
+            OMX_INDEXTYPE index, void *params, size_t size) = 0;
 
     virtual status_t setParameter(
-            node_id node, OMX_INDEXTYPE index,
-            const void *params, size_t size) = 0;
+            OMX_INDEXTYPE index, const void *params, size_t size) = 0;
 
     virtual status_t getConfig(
-            node_id node, OMX_INDEXTYPE index,
-            void *params, size_t size) = 0;
+            OMX_INDEXTYPE index, void *params, size_t size) = 0;
 
     virtual status_t setConfig(
-            node_id node, OMX_INDEXTYPE index,
-            const void *params, size_t size) = 0;
+            OMX_INDEXTYPE index, const void *params, size_t size) = 0;
 
-    virtual status_t getState(
-            node_id node, OMX_STATETYPE* state) = 0;
+    virtual status_t getState(OMX_STATETYPE* state) = 0;
 
     // This will set *type to previous metadata buffer type on OMX error (not on binder error), and
     // new metadata buffer type on success.
     virtual status_t storeMetaDataInBuffers(
-            node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type = NULL) = 0;
+            OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type = NULL) = 0;
 
     virtual status_t prepareForAdaptivePlayback(
-            node_id node, OMX_U32 portIndex, OMX_BOOL enable,
+            OMX_U32 portIndex, OMX_BOOL enable,
             OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) = 0;
 
     virtual status_t configureVideoTunnelMode(
-            node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
+            OMX_U32 portIndex, OMX_BOOL tunneled,
             OMX_U32 audioHwSync, native_handle_t **sidebandHandle) = 0;
 
     virtual status_t enableNativeBuffers(
-            node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) = 0;
+            OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) = 0;
 
     virtual status_t getGraphicBufferUsage(
-            node_id node, OMX_U32 port_index, OMX_U32* usage) = 0;
+            OMX_U32 port_index, OMX_U32* usage) = 0;
 
     // Use |params| as an OMX buffer, but limit the size of the OMX buffer to |allottedSize|.
     virtual status_t useBuffer(
-            node_id node, OMX_U32 port_index, const sp<IMemory> &params,
+            OMX_U32 port_index, const sp<IMemory> &params,
             buffer_id *buffer, OMX_U32 allottedSize) = 0;
 
     virtual status_t useGraphicBuffer(
-            node_id node, OMX_U32 port_index,
+            OMX_U32 port_index,
             const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) = 0;
 
     virtual status_t updateGraphicBufferInMeta(
-            node_id node, OMX_U32 port_index,
+            OMX_U32 port_index,
             const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) = 0;
 
     virtual status_t updateNativeHandleInMeta(
-            node_id node, OMX_U32 port_index,
+            OMX_U32 port_index,
             const sp<NativeHandle> &nativeHandle, buffer_id buffer) = 0;
 
     // This will set *type to resulting metadata buffer type on OMX error (not on binder error) as
     // well as on success.
     virtual status_t createInputSurface(
-            node_id node, OMX_U32 port_index, android_dataspace dataSpace,
+            OMX_U32 port_index, android_dataspace dataSpace,
             sp<IGraphicBufferProducer> *bufferProducer,
             sp<IGraphicBufferSource> *bufferSource,
             MetadataBufferType *type = NULL) = 0;
 
-    virtual status_t createPersistentInputSurface(
-            sp<IGraphicBufferProducer> *bufferProducer,
-            sp<IGraphicBufferConsumer> *bufferConsumer) = 0;
-
     // This will set *type to resulting metadata buffer type on OMX error (not on binder error) as
     // well as on success.
     virtual status_t setInputSurface(
-            node_id node, OMX_U32 port_index,
+            OMX_U32 port_index,
             const sp<IGraphicBufferConsumer> &bufferConsumer,
             sp<IGraphicBufferSource> *bufferSource,
             MetadataBufferType *type) = 0;
@@ -149,32 +153,28 @@
     // 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 allocateSecureBuffer(
-            node_id node, OMX_U32 port_index, size_t size,
-            buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle) = 0;
+            OMX_U32 port_index, size_t size, buffer_id *buffer,
+            void **buffer_data, sp<NativeHandle> *native_handle) = 0;
 
     // Allocate an OMX buffer of size |allotedSize|. Use |params| as the backup buffer, which
     // may be larger.
     virtual status_t allocateBufferWithBackup(
-            node_id node, OMX_U32 port_index, const sp<IMemory> &params,
+            OMX_U32 port_index, const sp<IMemory> &params,
             buffer_id *buffer, OMX_U32 allottedSize) = 0;
 
     virtual status_t freeBuffer(
-            node_id node, OMX_U32 port_index, buffer_id buffer) = 0;
+            OMX_U32 port_index, buffer_id buffer) = 0;
 
-    enum {
-        kFenceTimeoutMs = 1000
-    };
     // Calls OMX_FillBuffer on buffer, and passes |fenceFd| to component if it supports
     // fences. Otherwise, it waits on |fenceFd| before calling OMX_FillBuffer.
     // Takes ownership of |fenceFd| even if this call fails.
-    virtual status_t fillBuffer(node_id node, buffer_id buffer, int fenceFd = -1) = 0;
+    virtual status_t fillBuffer(buffer_id buffer, int fenceFd = -1) = 0;
 
     // Calls OMX_EmptyBuffer on buffer (after updating buffer header with |range_offset|,
     // |range_length|, |flags| and |timestamp|). Passes |fenceFd| to component if it
     // supports fences. Otherwise, it waits on |fenceFd| before calling OMX_EmptyBuffer.
     // Takes ownership of |fenceFd| even if this call fails.
     virtual status_t emptyBuffer(
-            node_id node,
             buffer_id buffer,
             OMX_U32 range_offset, OMX_U32 range_length,
             OMX_U32 flags, OMX_TICKS timestamp, int fenceFd = -1) = 0;
@@ -186,13 +186,11 @@
     // timestamp on the filled buffer corresponding to this frame will be modified to
     // |origTimestamp| after it's filled.
     virtual status_t emptyGraphicBuffer(
-            node_id node,
             buffer_id buffer,
             const sp<GraphicBuffer> &graphicBuffer, OMX_U32 flags,
             OMX_TICKS timestamp, OMX_TICKS origTimestamp, int fenceFd) = 0;
 
     virtual status_t getExtensionIndex(
-            node_id node,
             const char *parameter_name,
             OMX_INDEXTYPE *index) = 0;
 
@@ -207,7 +205,6 @@
         FRAME_RENDERED,
     } type;
 
-    IOMX::node_id node;
     int fenceFd; // used for EMPTY_BUFFER_DONE and FILL_BUFFER_DONE; client must close this
 
     union {
@@ -254,13 +251,24 @@
 
 class BnOMX : public BnInterface<IOMX> {
 public:
+    virtual bool livesLocally() {
+        return true;
+    }
+
+    virtual status_t onTransact(
+            uint32_t code, const Parcel &data, Parcel *reply,
+            uint32_t flags = 0);
+};
+
+class BnOMXNode : public BnInterface<IOMXNode> {
+public:
     virtual status_t onTransact(
             uint32_t code, const Parcel &data, Parcel *reply,
             uint32_t flags = 0);
 
 protected:
     // check if the codec is secure.
-    virtual bool isSecure(IOMX::node_id node) {
+    virtual bool isSecure() const {
         return false;
     }
 };
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 6f6f2f9..e83a8f2 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -244,8 +244,9 @@
     uint32_t mFlags;
     uint32_t mQuirks;
     sp<IOMX> mOMX;
+    sp<IOMXNode> mOMXNode;
     sp<IBinder> mNodeBinder;
-    IOMX::node_id mNode;
+    int32_t mNodeGeneration;
     sp<MemoryDealer> mDealer[2];
 
     bool mUsingNativeWindow;
diff --git a/include/media/stagefright/MediaCodecList.h b/include/media/stagefright/MediaCodecList.h
index 44dbde0..430bc16 100644
--- a/include/media/stagefright/MediaCodecList.h
+++ b/include/media/stagefright/MediaCodecList.h
@@ -115,7 +115,6 @@
 
     Vector<sp<MediaCodecInfo> > mCodecInfos;
     sp<MediaCodecInfo> mCurrentInfo;
-    sp<IOMX> mOMX;
 
     MediaCodecList();
     ~MediaCodecList();
diff --git a/include/media/stagefright/OMXClient.h b/include/media/stagefright/OMXClient.h
index 2f14d06..6973405 100644
--- a/include/media/stagefright/OMXClient.h
+++ b/include/media/stagefright/OMXClient.h
@@ -18,10 +18,10 @@
 
 #define OMX_CLIENT_H_
 
-#include <media/IOMX.h>
-
 namespace android {
 
+class IOMX;
+
 class OMXClient {
 public:
     OMXClient();
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 5e6ac36..e25e56c 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -33,7 +33,6 @@
 
 enum {
     CONNECT = IBinder::FIRST_CALL_TRANSACTION,
-    LIVES_LOCALLY,
     LIST_NODES,
     ALLOCATE_NODE,
     FREE_NODE,
@@ -72,14 +71,8 @@
         : BpInterface<IOMX>(impl) {
     }
 
-    virtual bool livesLocally(node_id node, pid_t pid) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        data.writeInt32(pid);
-        remote()->transact(LIVES_LOCALLY, data, &reply);
-
-        return reply.readInt32() != 0;
+    virtual bool livesLocally() {
+        return false;
     }
 
     virtual status_t listNodes(List<ComponentInfo> *list) {
@@ -106,8 +99,7 @@
 
     virtual status_t allocateNode(
             const char *name, const sp<IOMXObserver> &observer,
-            sp<IBinder> *nodeBinder,
-            node_id *node) {
+            sp<IBinder> *nodeBinder, sp<IOMXNode> *omxNode) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
         data.writeCString(name);
@@ -116,261 +108,17 @@
 
         status_t err = reply.readInt32();
         if (err == OK) {
-            *node = (node_id)reply.readInt32();
+            *omxNode = IOMXNode::asInterface(reply.readStrongBinder());
             if (nodeBinder != NULL) {
                 *nodeBinder = remote();
             }
         } else {
-            *node = 0;
+            omxNode->clear();
         }
 
         return err;
     }
 
-    virtual status_t freeNode(node_id node) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        remote()->transact(FREE_NODE, data, &reply);
-
-        return reply.readInt32();
-    }
-
-    virtual status_t sendCommand(
-            node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        data.writeInt32(cmd);
-        data.writeInt32(param);
-        remote()->transact(SEND_COMMAND, data, &reply);
-
-        return reply.readInt32();
-    }
-
-    virtual status_t getParameter(
-            node_id node, OMX_INDEXTYPE index,
-            void *params, size_t size) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        data.writeInt32(index);
-        data.writeInt64(size);
-        data.write(params, size);
-        remote()->transact(GET_PARAMETER, data, &reply);
-
-        status_t err = reply.readInt32();
-        if (err != OK) {
-            return err;
-        }
-
-        reply.read(params, size);
-
-        return OK;
-    }
-
-    virtual status_t setParameter(
-            node_id node, OMX_INDEXTYPE index,
-            const void *params, size_t size) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        data.writeInt32(index);
-        data.writeInt64(size);
-        data.write(params, size);
-        remote()->transact(SET_PARAMETER, data, &reply);
-
-        return reply.readInt32();
-    }
-
-    virtual status_t getConfig(
-            node_id node, OMX_INDEXTYPE index,
-            void *params, size_t size) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        data.writeInt32(index);
-        data.writeInt64(size);
-        data.write(params, size);
-        remote()->transact(GET_CONFIG, data, &reply);
-
-        status_t err = reply.readInt32();
-        if (err != OK) {
-            return err;
-        }
-
-        reply.read(params, size);
-
-        return OK;
-    }
-
-    virtual status_t setConfig(
-            node_id node, OMX_INDEXTYPE index,
-            const void *params, size_t size) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        data.writeInt32(index);
-        data.writeInt64(size);
-        data.write(params, size);
-        remote()->transact(SET_CONFIG, data, &reply);
-
-        return reply.readInt32();
-    }
-
-    virtual status_t getState(
-            node_id node, OMX_STATETYPE* state) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        remote()->transact(GET_STATE, data, &reply);
-
-        *state = static_cast<OMX_STATETYPE>(reply.readInt32());
-        return reply.readInt32();
-    }
-
-    virtual status_t enableNativeBuffers(
-            node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        data.writeInt32(port_index);
-        data.writeInt32((uint32_t)graphic);
-        data.writeInt32((uint32_t)enable);
-        remote()->transact(ENABLE_NATIVE_BUFFERS, data, &reply);
-
-        status_t err = reply.readInt32();
-        return err;
-    }
-
-    virtual status_t getGraphicBufferUsage(
-            node_id node, OMX_U32 port_index, OMX_U32* usage) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        data.writeInt32(port_index);
-        remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply);
-
-        status_t err = reply.readInt32();
-        *usage = reply.readInt32();
-        return err;
-    }
-
-    virtual status_t useBuffer(
-            node_id node, OMX_U32 port_index, const sp<IMemory> &params,
-            buffer_id *buffer, OMX_U32 allottedSize) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        data.writeInt32(port_index);
-        data.writeStrongBinder(IInterface::asBinder(params));
-        data.writeInt32(allottedSize);
-        remote()->transact(USE_BUFFER, data, &reply);
-
-        status_t err = reply.readInt32();
-        if (err != OK) {
-            *buffer = 0;
-
-            return err;
-        }
-
-        *buffer = (buffer_id)reply.readInt32();
-
-        return err;
-    }
-
-
-    virtual status_t useGraphicBuffer(
-            node_id node, OMX_U32 port_index,
-            const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        data.writeInt32(port_index);
-        data.write(*graphicBuffer);
-        remote()->transact(USE_GRAPHIC_BUFFER, data, &reply);
-
-        status_t err = reply.readInt32();
-        if (err != OK) {
-            *buffer = 0;
-
-            return err;
-        }
-
-        *buffer = (buffer_id)reply.readInt32();
-
-        return err;
-    }
-
-    virtual status_t updateGraphicBufferInMeta(
-            node_id node, OMX_U32 port_index,
-            const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        data.writeInt32(port_index);
-        data.write(*graphicBuffer);
-        data.writeInt32((int32_t)buffer);
-        remote()->transact(UPDATE_GRAPHIC_BUFFER_IN_META, data, &reply);
-
-        status_t err = reply.readInt32();
-        return err;
-    }
-
-    virtual status_t updateNativeHandleInMeta(
-            node_id node, OMX_U32 port_index,
-            const sp<NativeHandle> &nativeHandle, buffer_id buffer) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        data.writeInt32(port_index);
-        data.writeInt32(nativeHandle != NULL);
-        if (nativeHandle != NULL) {
-            data.writeNativeHandle(nativeHandle->handle());
-        }
-        data.writeInt32((int32_t)buffer);
-        remote()->transact(UPDATE_NATIVE_HANDLE_IN_META, data, &reply);
-
-        status_t err = reply.readInt32();
-        return err;
-    }
-
-    virtual status_t createInputSurface(
-            node_id node, OMX_U32 port_index, android_dataspace dataSpace,
-            sp<IGraphicBufferProducer> *bufferProducer,
-            sp<IGraphicBufferSource> *bufferSource,
-            MetadataBufferType *type) {
-        Parcel data, reply;
-        status_t err;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
-        data.writeInt32(port_index);
-        data.writeInt32(dataSpace);
-        err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply);
-        if (err != OK) {
-            ALOGW("binder transaction failed: %d", err);
-            return err;
-        }
-
-        // read type even if createInputSurface failed
-        int negotiatedType = reply.readInt32();
-        if (type != NULL) {
-            *type = (MetadataBufferType)negotiatedType;
-        }
-
-        err = reply.readInt32();
-        if (err != OK) {
-            return err;
-        }
-
-        *bufferProducer = IGraphicBufferProducer::asInterface(
-                reply.readStrongBinder());
-        *bufferSource = IGraphicBufferSource::asInterface(
-                reply.readStrongBinder());
-
-        return err;
-    }
-
     virtual status_t createPersistentInputSurface(
             sp<IGraphicBufferProducer> *bufferProducer,
             sp<IGraphicBufferConsumer> *bufferConsumer) {
@@ -395,16 +143,252 @@
 
         return err;
     }
+};
+
+class BpOMXNode : public BpInterface<IOMXNode> {
+public:
+    explicit BpOMXNode(const sp<IBinder> &impl)
+        : BpInterface<IOMXNode>(impl) {
+    }
+
+    virtual status_t freeNode() {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
+        remote()->transact(FREE_NODE, data, &reply);
+
+        return reply.readInt32();
+    }
+
+    virtual status_t sendCommand(
+            OMX_COMMANDTYPE cmd, OMX_S32 param) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
+        data.writeInt32(cmd);
+        data.writeInt32(param);
+        remote()->transact(SEND_COMMAND, data, &reply);
+
+        return reply.readInt32();
+    }
+
+    virtual status_t getParameter(
+            OMX_INDEXTYPE index,
+            void *params, size_t size) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
+        data.writeInt32(index);
+        data.writeInt64(size);
+        data.write(params, size);
+        remote()->transact(GET_PARAMETER, data, &reply);
+
+        status_t err = reply.readInt32();
+        if (err != OK) {
+            return err;
+        }
+
+        reply.read(params, size);
+
+        return OK;
+    }
+
+    virtual status_t setParameter(
+            OMX_INDEXTYPE index,
+            const void *params, size_t size) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
+        data.writeInt32(index);
+        data.writeInt64(size);
+        data.write(params, size);
+        remote()->transact(SET_PARAMETER, data, &reply);
+
+        return reply.readInt32();
+    }
+
+    virtual status_t getConfig(
+            OMX_INDEXTYPE index,
+            void *params, size_t size) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
+        data.writeInt32(index);
+        data.writeInt64(size);
+        data.write(params, size);
+        remote()->transact(GET_CONFIG, data, &reply);
+
+        status_t err = reply.readInt32();
+        if (err != OK) {
+            return err;
+        }
+
+        reply.read(params, size);
+
+        return OK;
+    }
+
+    virtual status_t setConfig(
+            OMX_INDEXTYPE index,
+            const void *params, size_t size) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
+        data.writeInt32(index);
+        data.writeInt64(size);
+        data.write(params, size);
+        remote()->transact(SET_CONFIG, data, &reply);
+
+        return reply.readInt32();
+    }
+
+    virtual status_t getState(
+            OMX_STATETYPE* state) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
+        remote()->transact(GET_STATE, data, &reply);
+
+        *state = static_cast<OMX_STATETYPE>(reply.readInt32());
+        return reply.readInt32();
+    }
+
+    virtual status_t enableNativeBuffers(
+            OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
+        data.writeInt32(port_index);
+        data.writeInt32((uint32_t)graphic);
+        data.writeInt32((uint32_t)enable);
+        remote()->transact(ENABLE_NATIVE_BUFFERS, data, &reply);
+
+        status_t err = reply.readInt32();
+        return err;
+    }
+
+    virtual status_t getGraphicBufferUsage(
+            OMX_U32 port_index, OMX_U32* usage) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
+        data.writeInt32(port_index);
+        remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply);
+
+        status_t err = reply.readInt32();
+        *usage = reply.readInt32();
+        return err;
+    }
+
+    virtual status_t useBuffer(
+            OMX_U32 port_index, const sp<IMemory> &params,
+            buffer_id *buffer, OMX_U32 allottedSize) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
+        data.writeInt32(port_index);
+        data.writeStrongBinder(IInterface::asBinder(params));
+        data.writeInt32(allottedSize);
+        remote()->transact(USE_BUFFER, data, &reply);
+
+        status_t err = reply.readInt32();
+        if (err != OK) {
+            *buffer = 0;
+
+            return err;
+        }
+
+        *buffer = (buffer_id)reply.readInt32();
+
+        return err;
+    }
+
+
+    virtual status_t useGraphicBuffer(
+            OMX_U32 port_index,
+            const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
+        data.writeInt32(port_index);
+        data.write(*graphicBuffer);
+        remote()->transact(USE_GRAPHIC_BUFFER, data, &reply);
+
+        status_t err = reply.readInt32();
+        if (err != OK) {
+            *buffer = 0;
+
+            return err;
+        }
+
+        *buffer = (buffer_id)reply.readInt32();
+
+        return err;
+    }
+
+    virtual status_t updateGraphicBufferInMeta(
+            OMX_U32 port_index,
+            const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
+        data.writeInt32(port_index);
+        data.write(*graphicBuffer);
+        data.writeInt32((int32_t)buffer);
+        remote()->transact(UPDATE_GRAPHIC_BUFFER_IN_META, data, &reply);
+
+        status_t err = reply.readInt32();
+        return err;
+    }
+
+    virtual status_t updateNativeHandleInMeta(
+            OMX_U32 port_index,
+            const sp<NativeHandle> &nativeHandle, buffer_id buffer) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
+        data.writeInt32(port_index);
+        data.writeInt32(nativeHandle != NULL);
+        if (nativeHandle != NULL) {
+            data.writeNativeHandle(nativeHandle->handle());
+        }
+        data.writeInt32((int32_t)buffer);
+        remote()->transact(UPDATE_NATIVE_HANDLE_IN_META, data, &reply);
+
+        status_t err = reply.readInt32();
+        return err;
+    }
+
+    virtual status_t createInputSurface(
+            OMX_U32 port_index, android_dataspace dataSpace,
+            sp<IGraphicBufferProducer> *bufferProducer,
+            sp<IGraphicBufferSource> *bufferSource,
+            MetadataBufferType *type) {
+        Parcel data, reply;
+        status_t err;
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
+        data.writeInt32(port_index);
+        data.writeInt32(dataSpace);
+        err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply);
+        if (err != OK) {
+            ALOGW("binder transaction failed: %d", err);
+            return err;
+        }
+
+        // read type even if createInputSurface failed
+        int negotiatedType = reply.readInt32();
+        if (type != NULL) {
+            *type = (MetadataBufferType)negotiatedType;
+        }
+
+        err = reply.readInt32();
+        if (err != OK) {
+            return err;
+        }
+
+        *bufferProducer = IGraphicBufferProducer::asInterface(
+                reply.readStrongBinder());
+        *bufferSource = IGraphicBufferSource::asInterface(
+                reply.readStrongBinder());
+
+        return err;
+    }
 
     virtual status_t setInputSurface(
-            node_id node, OMX_U32 port_index,
+            OMX_U32 port_index,
             const sp<IGraphicBufferConsumer> &bufferConsumer,
             sp<IGraphicBufferSource> *bufferSource,
             MetadataBufferType *type) {
         Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
         status_t err;
-        data.writeInt32((int32_t)node);
         data.writeInt32(port_index);
         data.writeStrongBinder(IInterface::asBinder(bufferConsumer));
 
@@ -433,10 +417,9 @@
     }
 
     virtual status_t storeMetaDataInBuffers(
-            node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) {
+            OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) {
         Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
         data.writeInt32(port_index);
         data.writeInt32((int32_t)enable);
         data.writeInt32(type == NULL ? kMetadataBufferTypeANWBuffer : *type);
@@ -453,11 +436,10 @@
     }
 
     virtual status_t prepareForAdaptivePlayback(
-            node_id node, OMX_U32 port_index, OMX_BOOL enable,
+            OMX_U32 port_index, OMX_BOOL enable,
             OMX_U32 max_width, OMX_U32 max_height) {
         Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
         data.writeInt32(port_index);
         data.writeInt32((int32_t)enable);
         data.writeInt32(max_width);
@@ -469,11 +451,10 @@
     }
 
     virtual status_t configureVideoTunnelMode(
-            node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
+            OMX_U32 portIndex, OMX_BOOL tunneled,
             OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) {
         Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
         data.writeInt32(portIndex);
         data.writeInt32((int32_t)tunneled);
         data.writeInt32(audioHwSync);
@@ -488,11 +469,10 @@
 
 
     virtual status_t allocateSecureBuffer(
-            node_id node, OMX_U32 port_index, size_t size,
+            OMX_U32 port_index, size_t size,
             buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle) {
         Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
         data.writeInt32(port_index);
         data.writeInt64(size);
         remote()->transact(ALLOC_SECURE_BUFFER, data, &reply);
@@ -517,11 +497,10 @@
     }
 
     virtual status_t allocateBufferWithBackup(
-            node_id node, OMX_U32 port_index, const sp<IMemory> &params,
+            OMX_U32 port_index, const sp<IMemory> &params,
             buffer_id *buffer, OMX_U32 allottedSize) {
         Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
         data.writeInt32(port_index);
         data.writeStrongBinder(IInterface::asBinder(params));
         data.writeInt32(allottedSize);
@@ -540,10 +519,9 @@
     }
 
     virtual status_t freeBuffer(
-            node_id node, OMX_U32 port_index, buffer_id buffer) {
+            OMX_U32 port_index, buffer_id buffer) {
         Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
         data.writeInt32(port_index);
         data.writeInt32((int32_t)buffer);
         remote()->transact(FREE_BUFFER, data, &reply);
@@ -551,10 +529,9 @@
         return reply.readInt32();
     }
 
-    virtual status_t fillBuffer(node_id node, buffer_id buffer, int fenceFd) {
+    virtual status_t fillBuffer(buffer_id buffer, int fenceFd) {
         Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
         data.writeInt32((int32_t)buffer);
         data.writeInt32(fenceFd >= 0);
         if (fenceFd >= 0) {
@@ -566,13 +543,11 @@
     }
 
     virtual status_t emptyBuffer(
-            node_id node,
             buffer_id buffer,
             OMX_U32 range_offset, OMX_U32 range_length,
             OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
         Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
         data.writeInt32((int32_t)buffer);
         data.writeInt32(range_offset);
         data.writeInt32(range_length);
@@ -588,13 +563,11 @@
     }
 
     virtual status_t emptyGraphicBuffer(
-            node_id node,
             buffer_id buffer,
             const sp<GraphicBuffer> &graphicBuffer, OMX_U32 flags,
             OMX_TICKS timestamp, OMX_TICKS origTimestamp, int fenceFd) {
         Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
         data.writeInt32((int32_t)buffer);
         data.write(*graphicBuffer);
         data.writeInt32(flags);
@@ -610,12 +583,10 @@
     }
 
     virtual status_t getExtensionIndex(
-            node_id node,
             const char *parameter_name,
             OMX_INDEXTYPE *index) {
         Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)node);
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
         data.writeCString(parameter_name);
 
         remote()->transact(GET_EXTENSION_INDEX, data, &reply);
@@ -632,8 +603,7 @@
 
     virtual status_t dispatchMessage(const omx_message &msg) {
         Parcel data, reply;
-        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        data.writeInt32((int32_t)msg.node);
+        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
         data.writeInt32(msg.fenceFd >= 0);
         if (msg.fenceFd >= 0) {
             data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
@@ -648,6 +618,7 @@
 };
 
 IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
+IMPLEMENT_META_INTERFACE(OMXNode, "android.hardware.IOMXNode");
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -660,16 +631,6 @@
 status_t BnOMX::onTransact(
     uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
     switch (code) {
-        case LIVES_LOCALLY:
-        {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
-            node_id node = (node_id)data.readInt32();
-            pid_t pid = (pid_t)data.readInt32();
-            reply->writeInt32(livesLocally(node, pid));
-
-            return OK;
-        }
-
         case LIST_NODES:
         {
             CHECK_OMX_INTERFACE(IOMX, data, reply);
@@ -708,40 +669,64 @@
                 return NO_ERROR;
             }
 
-            node_id node;
+            sp<IOMXNode> omxNode;
 
-            status_t err = allocateNode(name, observer,
-                    NULL /* nodeBinder */, &node);
+            status_t err = allocateNode(
+                    name, observer, NULL /* nodeBinder */, &omxNode);
+
             reply->writeInt32(err);
             if (err == OK) {
-                reply->writeInt32((int32_t)node);
+                reply->writeStrongBinder(IInterface::asBinder(omxNode));
             }
 
             return NO_ERROR;
         }
 
-        case FREE_NODE:
+        case CREATE_PERSISTENT_INPUT_SURFACE:
         {
             CHECK_OMX_INTERFACE(IOMX, data, reply);
 
-            node_id node = (node_id)data.readInt32();
+            sp<IGraphicBufferProducer> bufferProducer;
+            sp<IGraphicBufferConsumer> bufferConsumer;
+            status_t err = createPersistentInputSurface(
+                    &bufferProducer, &bufferConsumer);
 
-            reply->writeInt32(freeNode(node));
+            reply->writeInt32(err);
+
+            if (err == OK) {
+                reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
+                reply->writeStrongBinder(IInterface::asBinder(bufferConsumer));
+            }
+
+            return NO_ERROR;
+        }
+
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+status_t BnOMXNode::onTransact(
+    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
+    switch (code) {
+        case FREE_NODE:
+        {
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
+
+            reply->writeInt32(freeNode());
 
             return NO_ERROR;
         }
 
         case SEND_COMMAND:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
-
-            node_id node = (node_id)data.readInt32();
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
             OMX_COMMANDTYPE cmd =
                 static_cast<OMX_COMMANDTYPE>(data.readInt32());
 
             OMX_S32 param = data.readInt32();
-            reply->writeInt32(sendCommand(node, cmd, param));
+            reply->writeInt32(sendCommand(cmd, param));
 
             return NO_ERROR;
         }
@@ -751,9 +736,8 @@
         case GET_CONFIG:
         case SET_CONFIG:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
 
             size_t size = data.readInt64();
@@ -800,16 +784,16 @@
                             } else {
                                 switch (code) {
                                     case GET_PARAMETER:
-                                        err = getParameter(node, index, params, size);
+                                        err = getParameter(index, params, size);
                                         break;
                                     case SET_PARAMETER:
-                                        err = setParameter(node, index, params, size);
+                                        err = setParameter(index, params, size);
                                         break;
                                     case GET_CONFIG:
-                                        err = getConfig(node, index, params, size);
+                                        err = getConfig(index, params, size);
                                         break;
                                     case SET_CONFIG:
-                                        err = setConfig(node, index, params, size);
+                                        err = setConfig(index, params, size);
                                         break;
                                     default:
                                         TRESPASS();
@@ -838,12 +822,11 @@
 
         case GET_STATE:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_STATETYPE state = OMX_StateInvalid;
 
-            status_t err = getState(node, &state);
+            status_t err = getState(&state);
             reply->writeInt32(state);
             reply->writeInt32(err);
 
@@ -852,14 +835,13 @@
 
         case ENABLE_NATIVE_BUFFERS:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
             OMX_BOOL graphic = (OMX_BOOL)data.readInt32();
             OMX_BOOL enable = (OMX_BOOL)data.readInt32();
 
-            status_t err = enableNativeBuffers(node, port_index, graphic, enable);
+            status_t err = enableNativeBuffers(port_index, graphic, enable);
             reply->writeInt32(err);
 
             return NO_ERROR;
@@ -867,13 +849,12 @@
 
         case GET_GRAPHIC_BUFFER_USAGE:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
 
             OMX_U32 usage = 0;
-            status_t err = getGraphicBufferUsage(node, port_index, &usage);
+            status_t err = getGraphicBufferUsage(port_index, &usage);
             reply->writeInt32(err);
             reply->writeInt32(usage);
 
@@ -882,9 +863,8 @@
 
         case USE_BUFFER:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
             sp<IMemory> params =
                 interface_cast<IMemory>(data.readStrongBinder());
@@ -897,7 +877,7 @@
             }
 
             buffer_id buffer;
-            status_t err = useBuffer(node, port_index, params, &buffer, allottedSize);
+            status_t err = useBuffer(port_index, params, &buffer, allottedSize);
             reply->writeInt32(err);
 
             if (err == OK) {
@@ -909,16 +889,15 @@
 
         case USE_GRAPHIC_BUFFER:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
             sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
             data.read(*graphicBuffer);
 
             buffer_id buffer;
             status_t err = useGraphicBuffer(
-                    node, port_index, graphicBuffer, &buffer);
+                    port_index, graphicBuffer, &buffer);
             reply->writeInt32(err);
 
             if (err == OK) {
@@ -930,16 +909,15 @@
 
         case UPDATE_GRAPHIC_BUFFER_IN_META:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
             sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
             data.read(*graphicBuffer);
             buffer_id buffer = (buffer_id)data.readInt32();
 
             status_t err = updateGraphicBufferInMeta(
-                    node, port_index, graphicBuffer, buffer);
+                    port_index, graphicBuffer, buffer);
             reply->writeInt32(err);
 
             return NO_ERROR;
@@ -947,9 +925,8 @@
 
         case UPDATE_NATIVE_HANDLE_IN_META:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
             native_handle *handle = NULL;
             if (data.readInt32()) {
@@ -958,7 +935,7 @@
             buffer_id buffer = (buffer_id)data.readInt32();
 
             status_t err = updateNativeHandleInMeta(
-                    node, port_index, NativeHandle::create(handle, true /* ownshandle */), buffer);
+                    port_index, NativeHandle::create(handle, true /* ownshandle */), buffer);
             reply->writeInt32(err);
 
             return NO_ERROR;
@@ -966,9 +943,8 @@
 
         case CREATE_INPUT_SURFACE:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
             android_dataspace dataSpace = (android_dataspace)data.readInt32();
 
@@ -976,7 +952,7 @@
             sp<IGraphicBufferSource> bufferSource;
             MetadataBufferType type = kMetadataBufferTypeInvalid;
             status_t err = createInputSurface(
-                    node, port_index, dataSpace, &bufferProducer, &bufferSource, &type);
+                    port_index, dataSpace, &bufferProducer, &bufferSource, &type);
 
             if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
                 android_errorWriteLog(0x534e4554, "26324358");
@@ -993,30 +969,10 @@
             return NO_ERROR;
         }
 
-        case CREATE_PERSISTENT_INPUT_SURFACE:
-        {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
-
-            sp<IGraphicBufferProducer> bufferProducer;
-            sp<IGraphicBufferConsumer> bufferConsumer;
-            status_t err = createPersistentInputSurface(
-                    &bufferProducer, &bufferConsumer);
-
-            reply->writeInt32(err);
-
-            if (err == OK) {
-                reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
-                reply->writeStrongBinder(IInterface::asBinder(bufferConsumer));
-            }
-
-            return NO_ERROR;
-        }
-
         case SET_INPUT_SURFACE:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
 
             sp<IGraphicBufferConsumer> bufferConsumer =
@@ -1029,7 +985,7 @@
             if (bufferConsumer == NULL) {
                 ALOGE("b/26392700");
             } else {
-                err = setInputSurface(node, port_index, bufferConsumer, &bufferSource, &type);
+                err = setInputSurface(port_index, bufferConsumer, &bufferSource, &type);
 
                 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
                    android_errorWriteLog(0x534e4554, "26324358");
@@ -1046,14 +1002,13 @@
 
         case STORE_META_DATA_IN_BUFFERS:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
             OMX_BOOL enable = (OMX_BOOL)data.readInt32();
 
             MetadataBufferType type = (MetadataBufferType)data.readInt32();
-            status_t err = storeMetaDataInBuffers(node, port_index, enable, &type);
+            status_t err = storeMetaDataInBuffers(port_index, enable, &type);
 
             reply->writeInt32(type);
             reply->writeInt32(err);
@@ -1063,16 +1018,15 @@
 
         case PREPARE_FOR_ADAPTIVE_PLAYBACK:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
             OMX_BOOL enable = (OMX_BOOL)data.readInt32();
             OMX_U32 max_width = data.readInt32();
             OMX_U32 max_height = data.readInt32();
 
             status_t err = prepareForAdaptivePlayback(
-                    node, port_index, enable, max_width, max_height);
+                    port_index, enable, max_width, max_height);
             reply->writeInt32(err);
 
             return NO_ERROR;
@@ -1080,16 +1034,15 @@
 
         case CONFIGURE_VIDEO_TUNNEL_MODE:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
             OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
             OMX_U32 audio_hw_sync = data.readInt32();
 
             native_handle_t *sideband_handle = NULL;
             status_t err = configureVideoTunnelMode(
-                    node, port_index, tunneled, audio_hw_sync, &sideband_handle);
+                    port_index, tunneled, audio_hw_sync, &sideband_handle);
             reply->writeInt32(err);
             if(err == OK){
                 reply->writeNativeHandle(sideband_handle);
@@ -1100,11 +1053,10 @@
 
         case ALLOC_SECURE_BUFFER:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
-            if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) {
+            if (!isSecure() || port_index != 0 /* kPortIndexInput */) {
                 ALOGE("b/24310423");
                 reply->writeInt32(INVALID_OPERATION);
                 return NO_ERROR;
@@ -1116,7 +1068,7 @@
             void *buffer_data = NULL;
             sp<NativeHandle> native_handle;
             status_t err = allocateSecureBuffer(
-                    node, port_index, size, &buffer, &buffer_data, &native_handle);
+                    port_index, size, &buffer, &buffer_data, &native_handle);
             reply->writeInt32(err);
 
             if (err == OK) {
@@ -1132,9 +1084,8 @@
 
         case ALLOC_BUFFER_WITH_BACKUP:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
             sp<IMemory> params =
                 interface_cast<IMemory>(data.readStrongBinder());
@@ -1148,7 +1099,7 @@
 
             buffer_id buffer;
             status_t err = allocateBufferWithBackup(
-                    node, port_index, params, &buffer, allottedSize);
+                    port_index, params, &buffer, allottedSize);
 
             reply->writeInt32(err);
 
@@ -1161,34 +1112,31 @@
 
         case FREE_BUFFER:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             OMX_U32 port_index = data.readInt32();
             buffer_id buffer = (buffer_id)data.readInt32();
-            reply->writeInt32(freeBuffer(node, port_index, buffer));
+            reply->writeInt32(freeBuffer(port_index, buffer));
 
             return NO_ERROR;
         }
 
         case FILL_BUFFER:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             buffer_id buffer = (buffer_id)data.readInt32();
             bool haveFence = data.readInt32();
             int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
-            reply->writeInt32(fillBuffer(node, buffer, fenceFd));
+            reply->writeInt32(fillBuffer(buffer, fenceFd));
 
             return NO_ERROR;
         }
 
         case EMPTY_BUFFER:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             buffer_id buffer = (buffer_id)data.readInt32();
             OMX_U32 range_offset = data.readInt32();
             OMX_U32 range_length = data.readInt32();
@@ -1197,16 +1145,15 @@
             bool haveFence = data.readInt32();
             int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
             reply->writeInt32(emptyBuffer(
-                    node, buffer, range_offset, range_length, flags, timestamp, fenceFd));
+                    buffer, range_offset, range_length, flags, timestamp, fenceFd));
 
             return NO_ERROR;
         }
 
         case EMPTY_GRAPHIC_BUFFER:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             buffer_id buffer = (buffer_id)data.readInt32();
             sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
             data.read(*graphicBuffer);
@@ -1216,7 +1163,7 @@
             bool haveFence = data.readInt32();
             int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
             reply->writeInt32(emptyGraphicBuffer(
-                    node, buffer, graphicBuffer, flags,
+                    buffer, graphicBuffer, flags,
                     timestamp, origTimestamp, fenceFd));
 
             return NO_ERROR;
@@ -1224,9 +1171,8 @@
 
         case GET_EXTENSION_INDEX:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
 
-            node_id node = (node_id)data.readInt32();
             const char *parameter_name = data.readCString();
 
             if (parameter_name == NULL) {
@@ -1236,7 +1182,7 @@
             }
 
             OMX_INDEXTYPE index;
-            status_t err = getExtensionIndex(node, parameter_name, &index);
+            status_t err = getExtensionIndex(parameter_name, &index);
 
             reply->writeInt32(err);
 
@@ -1249,9 +1195,8 @@
 
         case DISPATCH_MESSAGE:
         {
-            CHECK_OMX_INTERFACE(IOMX, data, reply);
+            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
             omx_message msg;
-            msg.node = data.readInt32();
             int haveFence = data.readInt32();
             msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
             msg.type = (typeof(msg.type))data.readInt32();
@@ -1281,14 +1226,12 @@
     virtual void onMessages(const std::list<omx_message> &messages) {
         Parcel data, reply;
         std::list<omx_message>::const_iterator it = messages.cbegin();
-        bool first = true;
+        if (messages.empty()) {
+            return;
+        }
+        data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
         while (it != messages.cend()) {
             const omx_message &msg = *it++;
-            if (first) {
-                data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
-                data.writeInt32(msg.node);
-                first = false;
-            }
             data.writeInt32(msg.fenceFd >= 0);
             if (msg.fenceFd >= 0) {
                 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
@@ -1297,10 +1240,8 @@
             data.write(&msg.u, sizeof(msg.u));
             ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg));
         }
-        if (!first) {
-            data.writeInt32(-1); // mark end
-            remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
-        }
+        data.writeInt32(-1); // mark end
+        remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
     }
 };
 
@@ -1312,7 +1253,6 @@
         case OBSERVER_ON_MSG:
         {
             CHECK_OMX_INTERFACE(IOMXObserver, data, reply);
-            IOMX::node_id node = data.readInt32();
             std::list<omx_message> messages;
             status_t err = FAILED_TRANSACTION; // must receive at least one message
             do {
@@ -1321,7 +1261,6 @@
                     break;
                 }
                 omx_message msg;
-                msg.node = node;
                 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
                 msg.type = (typeof(msg.type))data.readInt32();
                 err = data.read(&msg.u, sizeof(msg.u));
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index d36fca7..162ae22 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -156,15 +156,10 @@
         }
 
         sp<AMessage> notify = mNotify->dup();
-        bool first = true;
         sp<MessageList> msgList = new MessageList();
         for (std::list<omx_message>::const_iterator it = messages.cbegin();
               it != messages.cend(); ++it) {
             const omx_message &omx_msg = *it;
-            if (first) {
-                notify->setInt32("node", omx_msg.node);
-                first = false;
-            }
 
             sp<AMessage> msg = new AMessage;
             msg->setInt32("type", omx_msg.type);
@@ -516,7 +511,7 @@
 ACodec::ACodec()
     : mSampleRate(0),
       mQuirks(0),
-      mNode(0),
+      mNodeGeneration(0),
       mUsingNativeWindow(false),
       mNativeWindowUsageBits(0),
       mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN),
@@ -813,8 +808,8 @@
         InitOMXParams(&def);
         def.nPortIndex = portIndex;
 
-        err = mOMX->getParameter(
-                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+        err = mOMXNode->getParameter(
+                OMX_IndexParamPortDefinition, &def, sizeof(def));
 
         if (err == OK) {
             MetadataBufferType type =
@@ -896,8 +891,8 @@
 
                     void *ptr = NULL;
                     sp<NativeHandle> native_handle;
-                    err = mOMX->allocateSecureBuffer(
-                            mNode, portIndex, bufSize, &info.mBufferID,
+                    err = mOMXNode->allocateSecureBuffer(
+                            portIndex, bufSize, &info.mBufferID,
                             &ptr, &native_handle);
 
                     // TRICKY: this representation is unorthodox, but ACodec requires
@@ -915,10 +910,10 @@
                     info.mNativeHandle = native_handle;
                     info.mCodecData = info.mData;
                 } else if (mQuirks & requiresAllocateBufferBit) {
-                    err = mOMX->allocateBufferWithBackup(
-                            mNode, portIndex, mem, &info.mBufferID, allottedSize);
+                    err = mOMXNode->allocateBufferWithBackup(
+                            portIndex, mem, &info.mBufferID, allottedSize);
                 } else {
-                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID, allottedSize);
+                    err = mOMXNode->useBuffer(portIndex, mem, &info.mBufferID, allottedSize);
                 }
 
                 if (mem != NULL) {
@@ -979,15 +974,15 @@
     InitOMXParams(&def);
     def.nPortIndex = kPortIndexOutput;
 
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    status_t err = mOMXNode->getParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
 
     if (err != OK) {
         return err;
     }
 
     OMX_U32 usage = 0;
-    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
+    err = mOMXNode->getGraphicBufferUsage(kPortIndexOutput, &usage);
     if (err != 0) {
         ALOGW("querying usage flags from OMX IL component failed: %d", err);
         // XXX: Currently this error is logged, but not fatal.
@@ -1024,8 +1019,8 @@
     InitOMXParams(&def);
     def.nPortIndex = kPortIndexOutput;
 
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    status_t err = mOMXNode->getParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
 
     if (err == OK) {
         err = setupNativeWindowSizeFormatAndUsage(
@@ -1042,8 +1037,8 @@
     if (mTunneled) {
         ALOGV("Tunneled Playback: skipping native window buffer allocation.");
         def.nBufferCountActual = 0;
-        err = mOMX->setParameter(
-                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+        err = mOMXNode->setParameter(
+                OMX_IndexParamPortDefinition, &def, sizeof(def));
 
         *minUndequeuedBuffers = 0;
         *bufferCount = 0;
@@ -1078,8 +1073,8 @@
         OMX_U32 newBufferCount =
             def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
         def.nBufferCountActual = newBufferCount;
-        err = mOMX->setParameter(
-                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+        err = mOMXNode->setParameter(
+                OMX_IndexParamPortDefinition, &def, sizeof(def));
 
         if (err == OK) {
             *minUndequeuedBuffers += extraBuffers;
@@ -1145,8 +1140,8 @@
         mBuffers[kPortIndexOutput].push(info);
 
         IOMX::buffer_id bufferId;
-        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
-                &bufferId);
+        err = mOMXNode->useGraphicBuffer(
+                kPortIndexOutput, graphicBuffer, &bufferId);
         if (err != 0) {
             ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
                  "%d", i, err);
@@ -1231,8 +1226,8 @@
         info.mCodecRef = mem;
 
         // we use useBuffer for metadata regardless of quirks
-        err = mOMX->useBuffer(
-                mNode, kPortIndexOutput, mem, &info.mBufferID, mem->size());
+        err = mOMXNode->useBuffer(
+                kPortIndexOutput, mem, &info.mBufferID, mem->size());
         mBuffers[kPortIndexOutput].push(info);
 
         ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
@@ -1261,8 +1256,8 @@
             }
 
             sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
-            mOMX->updateGraphicBufferInMeta(
-                    mNode, kPortIndexOutput, graphicBuffer, info->mBufferID);
+            mOMXNode->updateGraphicBufferInMeta(
+                    kPortIndexOutput, graphicBuffer, info->mBufferID);
             info->mStatus = BufferInfo::OWNED_BY_US;
             info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy");
             info->mGraphicBuffer = graphicBuffer;
@@ -1301,7 +1296,7 @@
 
     --mMetadataBuffersToSubmit;
     info->checkWriteFence("submitOutputMetadataBuffer");
-    status_t err = mOMX->fillBuffer(mNode, info->mBufferID, info->mFenceFd);
+    status_t err = mOMXNode->fillBuffer(info->mBufferID, info->mFenceFd);
     info->mFenceFd = -1;
     if (err == OK) {
         info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
@@ -1499,9 +1494,8 @@
     mRenderTracker.untrackFrame(oldest->mRenderInfo);
     oldest->mRenderInfo = NULL;
 
-    mOMX->updateGraphicBufferInMeta(
-            mNode, kPortIndexOutput, oldest->mGraphicBuffer,
-            oldest->mBufferID);
+    mOMXNode->updateGraphicBufferInMeta(
+            kPortIndexOutput, oldest->mGraphicBuffer, oldest->mBufferID);
 
     if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
         VideoGrallocMetadata *grallocMeta =
@@ -1585,7 +1579,7 @@
             // fall through
 
         case BufferInfo::OWNED_BY_NATIVE_WINDOW:
-            err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID);
+            err = mOMXNode->freeBuffer(portIndex, info->mBufferID);
             break;
 
         default:
@@ -1603,7 +1597,7 @@
         info->mRenderInfo = NULL;
     }
 
-    // remove buffer even if mOMX->freeBuffer fails
+    // remove buffer even if mOMXNode->freeBuffer fails
     mBuffers[portIndex].removeAt(i);
     return err;
 }
@@ -1631,7 +1625,7 @@
     if (role == NULL) {
         return BAD_VALUE;
     }
-    status_t err = SetComponentRole(mOMX, mNode, role);
+    status_t err = SetComponentRole(mOMXNode, role);
     if (err != OK) {
         ALOGW("[%s] Failed to set standard component role '%s'.",
              mComponentName.c_str(), role);
@@ -1681,8 +1675,8 @@
             && msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
             && storeMeta != kMetadataBufferTypeInvalid) {
         mInputMetadataType = (MetadataBufferType)storeMeta;
-        err = mOMX->storeMetaDataInBuffers(
-                mNode, kPortIndexInput, OMX_TRUE, &mInputMetadataType);
+        err = mOMXNode->storeMetaDataInBuffers(
+                kPortIndexInput, OMX_TRUE, &mInputMetadataType);
         if (err != OK) {
             ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
                     mComponentName.c_str(), err);
@@ -1695,8 +1689,8 @@
         }
 
         uint32_t usageBits;
-        if (mOMX->getParameter(
-                mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
+        if (mOMXNode->getParameter(
+                (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
                 &usageBits, sizeof(usageBits)) == OK) {
             inputFormat->setInt32(
                     "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
@@ -1708,18 +1702,15 @@
             && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
             && prependSPSPPS != 0) {
         OMX_INDEXTYPE index;
-        err = mOMX->getExtensionIndex(
-                mNode,
-                "OMX.google.android.index.prependSPSPPSToIDRFrames",
-                &index);
+        err = mOMXNode->getExtensionIndex(
+                "OMX.google.android.index.prependSPSPPSToIDRFrames", &index);
 
         if (err == OK) {
             PrependSPSPPSToIDRFramesParams params;
             InitOMXParams(&params);
             params.bEnable = OMX_TRUE;
 
-            err = mOMX->setParameter(
-                    mNode, index, &params, sizeof(params));
+            err = mOMXNode->setParameter(index, &params, sizeof(params));
         }
 
         if (err != OK) {
@@ -1741,7 +1732,7 @@
             && storeMeta != 0);
 
         mOutputMetadataType = kMetadataBufferTypeNativeHandleSource;
-        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable, &mOutputMetadataType);
+        err = mOMXNode->storeMetaDataInBuffers(kPortIndexOutput, enable, &mOutputMetadataType);
         if (err != OK) {
             ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
                 mComponentName.c_str(), err);
@@ -1793,8 +1784,8 @@
 
         if (mFlags & kFlagIsSecure) {
             // use native_handles for secure input buffers
-            err = mOMX->enableNativeBuffers(
-                    mNode, kPortIndexInput, OMX_FALSE /* graphic */, OMX_TRUE);
+            err = mOMXNode->enableNativeBuffers(
+                    kPortIndexInput, OMX_FALSE /* graphic */, OMX_TRUE);
             ALOGI_IF(err != OK, "falling back to non-native_handles");
             err = OK; // ignore error for now
         }
@@ -1810,8 +1801,8 @@
             OMX_CONFIG_BOOLEANTYPE config;
             InitOMXParams(&config);
             config.bEnabled = (OMX_BOOL)enabled;
-            status_t temp = mOMX->setConfig(
-                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
+            status_t temp = mOMXNode->setConfig(
+                    (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
                     &config, sizeof(config));
             if (temp == OK) {
                 outputFormat->setInt32("auto-frc", enabled);
@@ -1842,8 +1833,8 @@
             if (msg->findInt32("max-width", &maxWidth) &&
                     msg->findInt32("max-height", &maxHeight)) {
 
-                err = mOMX->prepareForAdaptivePlayback(
-                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
+                err = mOMXNode->prepareForAdaptivePlayback(
+                        kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
                 if (err != OK) {
                     ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
                             mComponentName.c_str(), err);
@@ -1870,8 +1861,8 @@
 
             // Always try to enable dynamic output buffers on native surface
             mOutputMetadataType = kMetadataBufferTypeANWBuffer;
-            err = mOMX->storeMetaDataInBuffers(
-                    mNode, kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
+            err = mOMXNode->storeMetaDataInBuffers(
+                    kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
             if (err != OK) {
                 ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
                         mComponentName.c_str(), err);
@@ -1905,9 +1896,8 @@
                     ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
                             mComponentName.c_str(), maxWidth, maxHeight);
 
-                    err = mOMX->prepareForAdaptivePlayback(
-                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
-                            maxHeight);
+                    err = mOMXNode->prepareForAdaptivePlayback(
+                            kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
                     ALOGW_IF(err != OK,
                             "[%s] prepareForAdaptivePlayback failed w/ err %d",
                             mComponentName.c_str(), err);
@@ -1996,7 +1986,7 @@
                 ALOGD("[%s] Requested output format %#x and got %#x.",
                         mComponentName.c_str(), requestedColorFormat, colorFormat);
                 if (!IsFlexibleColorFormat(
-                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
+                        mOMXNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
                         || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
                     // device did not handle flex-YUV request for native window, fall back
                     // to SW renderer
@@ -2006,16 +1996,16 @@
                     haveNativeWindow = false;
                     usingSwRenderer = true;
                     if (storingMetadataInDecodedBuffers()) {
-                        err = mOMX->storeMetaDataInBuffers(
-                                mNode, kPortIndexOutput, OMX_FALSE, &mOutputMetadataType);
+                        err = mOMXNode->storeMetaDataInBuffers(
+                                kPortIndexOutput, OMX_FALSE, &mOutputMetadataType);
                         mOutputMetadataType = kMetadataBufferTypeInvalid; // just in case
                         // TODO: implement adaptive-playback support for bytebuffer mode.
                         // This is done by SW codecs, but most HW codecs don't support it.
                         inputFormat->setInt32("adaptive-playback", false);
                     }
                     if (err == OK) {
-                        err = mOMX->enableNativeBuffers(
-                                mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
+                        err = mOMXNode->enableNativeBuffers(
+                                kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
                     }
                     if (mFlags & kFlagIsGrallocUsageProtected) {
                         // fallback is not supported for protected playback
@@ -2257,8 +2247,8 @@
     OMX_PARAM_U32TYPE config;
     InitOMXParams(&config);
     config.nU32 = (OMX_U32)priority;
-    status_t temp = mOMX->setConfig(
-            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
+    status_t temp = mOMXNode->setConfig(
+            (OMX_INDEXTYPE)OMX_IndexConfigPriority,
             &config, sizeof(config));
     if (temp != OK) {
         ALOGI("codec does not support config priority (err %d)", temp);
@@ -2285,8 +2275,8 @@
     OMX_PARAM_U32TYPE config;
     InitOMXParams(&config);
     config.nU32 = rate;
-    status_t err = mOMX->setConfig(
-            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
+    status_t err = mOMXNode->setConfig(
+            (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
             &config, sizeof(config));
     if (err != OK) {
         ALOGI("codec does not support config operating rate (err %d)", err);
@@ -2298,8 +2288,8 @@
     OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
     InitOMXParams(&params);
     params.nPortIndex = kPortIndexOutput;
-    status_t err = mOMX->getConfig(
-            mNode, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
+    status_t err = mOMXNode->getConfig(
+            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
     if (err == OK) {
         *intraRefreshPeriod = params.nRefreshPeriod;
         return OK;
@@ -2310,8 +2300,8 @@
     InitOMXParams(&refreshParams);
     refreshParams.nPortIndex = kPortIndexOutput;
     refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams));
+    err = mOMXNode->getParameter(
+            OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams));
     if (err != OK || refreshParams.nCirMBs == 0) {
         *intraRefreshPeriod = 0;
         return OK;
@@ -2323,8 +2313,8 @@
     InitOMXParams(&def);
     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
     def.nPortIndex = kPortIndexOutput;
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    err = mOMXNode->getParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
     if (err != OK) {
         *intraRefreshPeriod = 0;
         return err;
@@ -2342,8 +2332,8 @@
     InitOMXParams(&params);
     params.nPortIndex = kPortIndexOutput;
     params.nRefreshPeriod = intraRefreshPeriod;
-    status_t err = mOMX->setConfig(
-            mNode, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
+    status_t err = mOMXNode->setConfig(
+            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
     if (err == OK) {
         return OK;
     }
@@ -2370,8 +2360,8 @@
         InitOMXParams(&def);
         OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
         def.nPortIndex = kPortIndexOutput;
-        err = mOMX->getParameter(
-                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+        err = mOMXNode->getParameter(
+                OMX_IndexParamPortDefinition, &def, sizeof(def));
         if (err != OK) {
             return err;
         }
@@ -2381,8 +2371,9 @@
         refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod);
     }
 
-    err = mOMX->setParameter(mNode, OMX_IndexParamVideoIntraRefresh,
-                             &refreshParams, sizeof(refreshParams));
+    err = mOMXNode->setParameter(
+            OMX_IndexParamVideoIntraRefresh,
+            &refreshParams, sizeof(refreshParams));
     if (err != OK) {
         return err;
     }
@@ -2425,9 +2416,9 @@
     InitOMXParams(&layerParams);
     layerParams.nPortIndex = kPortIndexOutput;
 
-    status_t err = mOMX->getParameter(
-        mNode, (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
-        &layerParams, sizeof(layerParams));
+    status_t err = mOMXNode->getParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
+            &layerParams, sizeof(layerParams));
 
     if (err != OK) {
         return err;
@@ -2447,8 +2438,8 @@
         layerConfig.nBLayerCountActual = numBLayers;
         layerConfig.bBitrateRatiosSpecified = OMX_FALSE;
 
-        err = mOMX->setConfig(
-                mNode, (OMX_INDEXTYPE)OMX_IndexConfigAndroidVideoTemporalLayering,
+        err = mOMXNode->setConfig(
+                (OMX_INDEXTYPE)OMX_IndexConfigAndroidVideoTemporalLayering,
                 &layerConfig, sizeof(layerConfig));
     } else {
         layerParams.ePattern = pattern;
@@ -2456,8 +2447,8 @@
         layerParams.nBLayerCountActual = numBLayers;
         layerParams.bBitrateRatiosSpecified = OMX_FALSE;
 
-        err = mOMX->setParameter(
-                mNode, (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
+        err = mOMXNode->setParameter(
+                (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
                 &layerParams, sizeof(layerParams));
     }
 
@@ -2474,8 +2465,8 @@
         return err;
     }
 
-    err = mOMX->getParameter(
-            mNode, (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
+    err = mOMXNode->getParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
             &layerParams, sizeof(layerParams));
 
     if (err == OK) {
@@ -2498,8 +2489,8 @@
     InitOMXParams(&def);
     def.nPortIndex = portIndex;
 
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    status_t err = mOMXNode->getParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
 
     if (err != OK) {
         return err;
@@ -2511,15 +2502,15 @@
 
     def.nBufferSize = size;
 
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    err = mOMXNode->setParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
 
     if (err != OK) {
         return err;
     }
 
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    err = mOMXNode->getParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
 
     if (err != OK) {
         return err;
@@ -2541,9 +2532,8 @@
     format.nPortIndex = portIndex;
     for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
         format.nIndex = index;
-        status_t err = mOMX->getParameter(
-                mNode, OMX_IndexParamAudioPortFormat,
-                &format, sizeof(format));
+        status_t err = mOMXNode->getParameter(
+                OMX_IndexParamAudioPortFormat, &format, sizeof(format));
 
         if (err != OK) {
             return err;
@@ -2561,8 +2551,8 @@
         }
     }
 
-    return mOMX->setParameter(
-            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
+    return mOMXNode->setParameter(
+            OMX_IndexParamAudioPortFormat, &format, sizeof(format));
 }
 
 status_t ACodec::setupAACCodec(
@@ -2594,8 +2584,8 @@
         InitOMXParams(&def);
         def.nPortIndex = kPortIndexOutput;
 
-        err = mOMX->getParameter(
-                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+        err = mOMXNode->getParameter(
+                OMX_IndexParamPortDefinition, &def, sizeof(def));
 
         if (err != OK) {
             return err;
@@ -2604,8 +2594,8 @@
         def.format.audio.bFlagErrorConcealment = OMX_TRUE;
         def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
 
-        err = mOMX->setParameter(
-                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+        err = mOMXNode->setParameter(
+                OMX_IndexParamPortDefinition, &def, sizeof(def));
 
         if (err != OK) {
             return err;
@@ -2615,8 +2605,8 @@
         InitOMXParams(&profile);
         profile.nPortIndex = kPortIndexOutput;
 
-        err = mOMX->getParameter(
-                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
+        err = mOMXNode->getParameter(
+                OMX_IndexParamAudioAac, &profile, sizeof(profile));
 
         if (err != OK) {
             return err;
@@ -2663,8 +2653,8 @@
         }
 
 
-        err = mOMX->setParameter(
-                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
+        err = mOMXNode->setParameter(
+                OMX_IndexParamAudioAac, &profile, sizeof(profile));
 
         if (err != OK) {
             return err;
@@ -2677,8 +2667,8 @@
     InitOMXParams(&profile);
     profile.nPortIndex = kPortIndexInput;
 
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
+    err = mOMXNode->getParameter(
+            OMX_IndexParamAudioAac, &profile, sizeof(profile));
 
     if (err != OK) {
         return err;
@@ -2702,10 +2692,12 @@
     presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
     presentation.nPCMLimiterEnable = pcmLimiterEnable;
 
-    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
+    status_t res = mOMXNode->setParameter(
+            OMX_IndexParamAudioAac, &profile, sizeof(profile));
     if (res == OK) {
         // optional parameters, will not cause configuration failure
-        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
+        mOMXNode->setParameter(
+                (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
                 &presentation, sizeof(presentation));
     } else {
         ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
@@ -2732,11 +2724,8 @@
     InitOMXParams(&def);
     def.nPortIndex = kPortIndexInput;
 
-    err = mOMX->getParameter(
-            mNode,
-            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
-            &def,
-            sizeof(def));
+    err = mOMXNode->getParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
 
     if (err != OK) {
         return err;
@@ -2745,11 +2734,8 @@
     def.nChannels = numChannels;
     def.nSampleRate = sampleRate;
 
-    return mOMX->setParameter(
-            mNode,
-            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
-            &def,
-            sizeof(def));
+    return mOMXNode->setParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
 }
 
 status_t ACodec::setupEAC3Codec(
@@ -2770,11 +2756,8 @@
     InitOMXParams(&def);
     def.nPortIndex = kPortIndexInput;
 
-    err = mOMX->getParameter(
-            mNode,
-            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
-            &def,
-            sizeof(def));
+    err = mOMXNode->getParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
 
     if (err != OK) {
         return err;
@@ -2783,11 +2766,8 @@
     def.nChannels = numChannels;
     def.nSampleRate = sampleRate;
 
-    return mOMX->setParameter(
-            mNode,
-            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
-            &def,
-            sizeof(def));
+    return mOMXNode->setParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
 }
 
 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
@@ -2840,8 +2820,8 @@
     InitOMXParams(&def);
     def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
 
-    status_t err =
-        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
+    status_t err = mOMXNode->getParameter(
+            OMX_IndexParamAudioAmr, &def, sizeof(def));
 
     if (err != OK) {
         return err;
@@ -2850,8 +2830,8 @@
     def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
     def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
 
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
+    err = mOMXNode->setParameter(
+            OMX_IndexParamAudioAmr, &def, sizeof(def));
 
     if (err != OK) {
         return err;
@@ -2881,13 +2861,13 @@
         def.nPortIndex = kPortIndexOutput;
 
         // configure compression level
-        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
+        status_t err = mOMXNode->getParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
         if (err != OK) {
             ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
             return err;
         }
         def.nCompressionLevel = compressionLevel;
-        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
+        err = mOMXNode->setParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
         if (err != OK) {
             ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
             return err;
@@ -2906,8 +2886,8 @@
     InitOMXParams(&def);
     def.nPortIndex = portIndex;
 
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    status_t err = mOMXNode->getParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
 
     if (err != OK) {
         return err;
@@ -2915,8 +2895,8 @@
 
     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
 
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    err = mOMXNode->setParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
 
     if (err != OK) {
         return err;
@@ -2926,8 +2906,8 @@
     InitOMXParams(&pcmParams);
     pcmParams.nPortIndex = portIndex;
 
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
+    err = mOMXNode->getParameter(
+            OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
 
     if (err != OK) {
         return err;
@@ -2958,15 +2938,15 @@
         return OMX_ErrorNone;
     }
 
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
+    err = mOMXNode->setParameter(
+            OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
     // if we could not set up raw format to non-16-bit, try with 16-bit
     // NOTE: we will also verify this via readback, in case codec ignores these fields
     if (err != OK && encoding != kAudioEncodingPcm16bit) {
         pcmParams.eNumData = OMX_NumericalDataSigned;
         pcmParams.nBitPerSample = 16;
-        err = mOMX->setParameter(
-                mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
+        err = mOMXNode->setParameter(
+                OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
     }
     return err;
 }
@@ -2975,8 +2955,8 @@
         int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
     native_handle_t* sidebandHandle;
 
-    status_t err = mOMX->configureVideoTunnelMode(
-            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
+    status_t err = mOMXNode->configureVideoTunnelMode(
+            kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
     if (err != OK) {
         ALOGE("configureVideoTunnelMode failed! (err %d).", err);
         return err;
@@ -3005,8 +2985,8 @@
 
     for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
         format.nIndex = index;
-        status_t err = mOMX->getParameter(
-                mNode, OMX_IndexParamVideoPortFormat,
+        status_t err = mOMXNode->getParameter(
+                OMX_IndexParamVideoPortFormat,
                 &format, sizeof(format));
 
         if (err != OK) {
@@ -3017,7 +2997,7 @@
         OMX_U32 flexibleEquivalent;
         if (compressionFormat == OMX_VIDEO_CodingUnused
                 && IsFlexibleColorFormat(
-                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
+                        mOMXNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
                 && colorFormat == flexibleEquivalent) {
             ALOGI("[%s] using color format %#x in place of %#x",
                     mComponentName.c_str(), format.eColorFormat, colorFormat);
@@ -3060,9 +3040,8 @@
         return UNKNOWN_ERROR;
     }
 
-    status_t err = mOMX->setParameter(
-            mNode, OMX_IndexParamVideoPortFormat,
-            &format, sizeof(format));
+    status_t err = mOMXNode->setParameter(
+            OMX_IndexParamVideoPortFormat, &format, sizeof(format));
 
     return err;
 }
@@ -3092,9 +3071,8 @@
 
     for (OMX_U32 index = 0; ; ++index) {
         format.nIndex = index;
-        status_t err = mOMX->getParameter(
-                mNode, OMX_IndexParamVideoPortFormat,
-                &format, sizeof(format));
+        status_t err = mOMXNode->getParameter(
+                OMX_IndexParamVideoPortFormat, &format, sizeof(format));
         if (err != OK) {
             // no more formats, pick legacy format if found
             if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
@@ -3121,15 +3099,14 @@
         OMX_U32 flexibleEquivalent;
         if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
                 && IsFlexibleColorFormat(
-                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
+                        mOMXNode, format.eColorFormat, false /* usingNativeBuffers */,
                         &flexibleEquivalent)
                 && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
             memcpy(&legacyFormat, &format, sizeof(format));
         }
     }
-    return mOMX->setParameter(
-            mNode, OMX_IndexParamVideoPortFormat,
-            &format, sizeof(format));
+    return mOMXNode->setParameter(
+            OMX_IndexParamVideoPortFormat, &format, sizeof(format));
 }
 
 static const struct VideoCodingMapEntry {
@@ -3185,14 +3162,14 @@
     status_t err;
     ALOGD("Setting [%s] %s port buffer number: %d", mComponentName.c_str(),
             portIndex == kPortIndexInput ? "input" : "output", bufferNum);
-    err = mOMX->getParameter(
-        mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    err = mOMXNode->getParameter(
+        OMX_IndexParamPortDefinition, &def, sizeof(def));
     if (err != OK) {
         return err;
     }
     def.nBufferCountActual = bufferNum;
-    err = mOMX->setParameter(
-        mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    err = mOMXNode->setParameter(
+        OMX_IndexParamPortDefinition, &def, sizeof(def));
     if (err != OK) {
         // Component could reject this request.
         ALOGW("Fail to set [%s] %s port buffer number: %d", mComponentName.c_str(),
@@ -3223,11 +3200,9 @@
         params.nPortIndex = kPortIndexInput;
         // Check if VP9 decoder advertises supported profiles.
         params.nProfileIndex = 0;
-        status_t err = mOMX->getParameter(
-                mNode,
+        status_t err = mOMXNode->getParameter(
                 OMX_IndexParamVideoProfileLevelQuerySupported,
-                &params,
-                sizeof(params));
+                &params, sizeof(params));
         mIsLegacyVP9Decoder = err != OK;
     }
 
@@ -3316,8 +3291,8 @@
 }
 
 status_t ACodec::initDescribeColorAspectsIndex() {
-    status_t err = mOMX->getExtensionIndex(
-            mNode, "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex);
+    status_t err = mOMXNode->getExtensionIndex(
+            "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex);
     if (err != OK) {
         mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0;
     }
@@ -3327,7 +3302,7 @@
 status_t ACodec::setCodecColorAspects(DescribeColorAspectsParams &params, bool verify) {
     status_t err = ERROR_UNSUPPORTED;
     if (mDescribeColorAspectsIndex) {
-        err = mOMX->setConfig(mNode, mDescribeColorAspectsIndex, &params, sizeof(params));
+        err = mOMXNode->setConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
     }
     ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
             mComponentName.c_str(),
@@ -3372,7 +3347,7 @@
 status_t ACodec::getCodecColorAspects(DescribeColorAspectsParams &params) {
     status_t err = ERROR_UNSUPPORTED;
     if (mDescribeColorAspectsIndex) {
-        err = mOMX->getConfig(mNode, mDescribeColorAspectsIndex, &params, sizeof(params));
+        err = mOMXNode->getConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
     }
     ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
             mComponentName.c_str(),
@@ -3594,8 +3569,8 @@
 }
 
 status_t ACodec::initDescribeHDRStaticInfoIndex() {
-    status_t err = mOMX->getExtensionIndex(
-            mNode, "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex);
+    status_t err = mOMXNode->getExtensionIndex(
+            "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex);
     if (err != OK) {
         mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0;
     }
@@ -3605,7 +3580,7 @@
 status_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams &params) {
     status_t err = ERROR_UNSUPPORTED;
     if (mDescribeHDRStaticInfoIndex) {
-        err = mOMX->setConfig(mNode, mDescribeHDRStaticInfoIndex, &params, sizeof(params));
+        err = mOMXNode->setConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
     }
 
     const HDRStaticInfo *info = &params.sInfo;
@@ -3626,7 +3601,7 @@
 status_t ACodec::getHDRStaticInfo(DescribeHDRStaticInfoParams &params) {
     status_t err = ERROR_UNSUPPORTED;
     if (mDescribeHDRStaticInfoIndex) {
-        err = mOMX->getConfig(mNode, mDescribeHDRStaticInfoIndex, &params, sizeof(params));
+        err = mOMXNode->getConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
     }
 
     ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
@@ -3665,8 +3640,8 @@
 
     def.nPortIndex = kPortIndexInput;
 
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    err = mOMXNode->getParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
 
     if (err != OK) {
         return err;
@@ -3716,8 +3691,8 @@
         video_def->eColorFormat = colorFormat;
     }
 
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    err = mOMXNode->setParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
 
     if (err != OK) {
         ALOGE("[%s] failed to set input port definition parameters.",
@@ -3747,8 +3722,8 @@
 
     def.nPortIndex = kPortIndexOutput;
 
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    err = mOMXNode->getParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
 
     if (err != OK) {
         return err;
@@ -3761,8 +3736,8 @@
     video_def->eCompressionFormat = compressionFormat;
     video_def->eColorFormat = OMX_COLOR_FormatUnused;
 
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    err = mOMXNode->setParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
 
     if (err != OK) {
         ALOGE("[%s] failed to set output port definition parameters.",
@@ -3891,9 +3866,8 @@
         params.nAirRef = ref;
     }
 
-    status_t err = mOMX->setParameter(
-            mNode, OMX_IndexParamVideoIntraRefresh,
-            &params, sizeof(params));
+    status_t err = mOMXNode->setParameter(
+            OMX_IndexParamVideoIntraRefresh, &params, sizeof(params));
     return err;
 }
 
@@ -3956,8 +3930,8 @@
     InitOMXParams(&mpeg4type);
     mpeg4type.nPortIndex = kPortIndexOutput;
 
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
+    status_t err = mOMXNode->getParameter(
+            OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
 
     if (err != OK) {
         return err;
@@ -3999,8 +3973,8 @@
         mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
     }
 
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
+    err = mOMXNode->setParameter(
+            OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
 
     if (err != OK) {
         return err;
@@ -4038,8 +4012,8 @@
     InitOMXParams(&h263type);
     h263type.nPortIndex = kPortIndexOutput;
 
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
+    status_t err = mOMXNode->getParameter(
+            OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
 
     if (err != OK) {
         return err;
@@ -4076,8 +4050,8 @@
     h263type.nPictureHeaderRepetition = 0;
     h263type.nGOBHeaderInterval = 0;
 
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
+    err = mOMXNode->setParameter(
+            OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
 
     if (err != OK) {
         return err;
@@ -4178,8 +4152,8 @@
     InitOMXParams(&h264type);
     h264type.nPortIndex = kPortIndexOutput;
 
-    err = mOMX->getParameter(
-            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
+    err = mOMXNode->getParameter(
+            OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
 
     if (err != OK) {
         return err;
@@ -4268,8 +4242,8 @@
     h264type.bMBAFF = OMX_FALSE;
     h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
 
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
+    err = mOMXNode->setParameter(
+            OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
 
     if (err != OK) {
         return err;
@@ -4285,8 +4259,8 @@
         OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layering;
         InitOMXParams(&layering);
         layering.nPortIndex = kPortIndexOutput;
-        if (mOMX->getParameter(
-                        mNode, (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
+        if (mOMXNode->getParameter(
+                        (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
                         &layering, sizeof(layering)) == OK
                 && layering.eSupportedPatterns
                 && layering.nBLayerCountMax == 0) {
@@ -4294,8 +4268,8 @@
             h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
             h264type.nAllowedPictureTypes &= ~OMX_VIDEO_PictureTypeB;
             ALOGI("disabling B-frames");
-            err = mOMX->setParameter(
-                    mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
+            err = mOMXNode->setParameter(
+                    OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
 
             if (err != OK) {
                 return err;
@@ -4330,8 +4304,8 @@
     hevcType.nPortIndex = kPortIndexOutput;
 
     status_t err = OK;
-    err = mOMX->getParameter(
-            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
+    err = mOMXNode->getParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
     if (err != OK) {
         return err;
     }
@@ -4354,8 +4328,8 @@
     // TODO: finer control?
     hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
 
-    err = mOMX->setParameter(
-            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
+    err = mOMXNode->setParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
     if (err != OK) {
         return err;
     }
@@ -4423,8 +4397,8 @@
     OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
     InitOMXParams(&vp8type);
     vp8type.nPortIndex = kPortIndexOutput;
-    status_t err = mOMX->getParameter(
-            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
+    status_t err = mOMXNode->getParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
             &vp8type, sizeof(vp8type));
 
     if (err == OK) {
@@ -4444,8 +4418,8 @@
             vp8type.nMaxQuantizer = 63;
         }
 
-        err = mOMX->setParameter(
-                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
+        err = mOMXNode->setParameter(
+                (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
                 &vp8type, sizeof(vp8type));
         if (err != OK) {
             ALOGW("Extended VP8 parameters set failed: %d", err);
@@ -4469,11 +4443,9 @@
 
     for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
         params.nProfileIndex = index;
-        status_t err = mOMX->getParameter(
-                mNode,
+        status_t err = mOMXNode->getParameter(
                 OMX_IndexParamVideoProfileLevelQuerySupported,
-                &params,
-                sizeof(params));
+                &params, sizeof(params));
 
         if (err != OK) {
             return err;
@@ -4501,9 +4473,8 @@
     InitOMXParams(&bitrateType);
     bitrateType.nPortIndex = kPortIndexOutput;
 
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamVideoBitrate,
-            &bitrateType, sizeof(bitrateType));
+    status_t err = mOMXNode->getParameter(
+            OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
 
     if (err != OK) {
         return err;
@@ -4512,9 +4483,8 @@
     bitrateType.eControlRate = bitrateMode;
     bitrateType.nTargetBitrate = bitrate;
 
-    return mOMX->setParameter(
-            mNode, OMX_IndexParamVideoBitrate,
-            &bitrateType, sizeof(bitrateType));
+    return mOMXNode->setParameter(
+            OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
 }
 
 status_t ACodec::setupErrorCorrectionParameters() {
@@ -4522,8 +4492,8 @@
     InitOMXParams(&errorCorrectionType);
     errorCorrectionType.nPortIndex = kPortIndexOutput;
 
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamVideoErrorCorrection,
+    status_t err = mOMXNode->getParameter(
+            OMX_IndexParamVideoErrorCorrection,
             &errorCorrectionType, sizeof(errorCorrectionType));
 
     if (err != OK) {
@@ -4536,8 +4506,8 @@
     errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
     errorCorrectionType.bEnableRVLC = OMX_FALSE;
 
-    return mOMX->setParameter(
-            mNode, OMX_IndexParamVideoErrorCorrection,
+    return mOMXNode->setParameter(
+            OMX_IndexParamVideoErrorCorrection,
             &errorCorrectionType, sizeof(errorCorrectionType));
 }
 
@@ -4551,8 +4521,8 @@
 
     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
 
-    status_t err = mOMX->getParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    status_t err = mOMXNode->getParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
     if (err != OK) {
         return err;
     }
@@ -4581,18 +4551,18 @@
         }
     }
 
-    err = mOMX->setParameter(
-            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    err = mOMXNode->setParameter(
+            OMX_IndexParamPortDefinition, &def, sizeof(def));
 
     return err;
 }
 
 status_t ACodec::initNativeWindow() {
     if (mNativeWindow != NULL) {
-        return mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_TRUE);
+        return mOMXNode->enableNativeBuffers(kPortIndexOutput, OMX_TRUE /* graphic */, OMX_TRUE);
     }
 
-    mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
+    mOMXNode->enableNativeBuffers(kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
     return OK;
 }
 
@@ -4680,7 +4650,7 @@
     InitOMXParams(&def);
     def.nPortIndex = portIndex;
 
-    status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+    status_t err = mOMXNode->getParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
     if (err != OK) {
         return err;
     }
@@ -4714,7 +4684,7 @@
                         describeParams.nSliceHeight = videoDef->nSliceHeight;
                         describeParams.bUsingNativeBuffers = OMX_FALSE;
 
-                        if (DescribeColorFormat(mOMX, mNode, describeParams)) {
+                        if (DescribeColorFormat(mOMXNode, describeParams)) {
                             notify->setBuffer(
                                     "image-data",
                                     ABuffer::CreateAsCopy(
@@ -4739,8 +4709,7 @@
                         InitOMXParams(&rect);
                         rect.nPortIndex = portIndex;
 
-                        if (mOMX->getConfig(
-                                    mNode,
+                        if (mOMXNode->getConfig(
                                     (portIndex == kPortIndexOutput ?
                                             OMX_IndexConfigCommonOutputCrop :
                                             OMX_IndexConfigCommonInputCrop),
@@ -4796,8 +4765,7 @@
                     OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
                     InitOMXParams(&vp8type);
                     vp8type.nPortIndex = kPortIndexOutput;
-                    status_t err = mOMX->getParameter(
-                            mNode,
+                    status_t err = mOMXNode->getParameter(
                             (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
                             &vp8type,
                             sizeof(vp8type));
@@ -4866,8 +4834,8 @@
                     InitOMXParams(&params);
                     params.nPortIndex = portIndex;
 
-                    err = mOMX->getParameter(
-                            mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
+                    err = mOMXNode->getParameter(
+                            OMX_IndexParamAudioPcm, &params, sizeof(params));
                     if (err != OK) {
                         return err;
                     }
@@ -4914,8 +4882,8 @@
                     InitOMXParams(&params);
                     params.nPortIndex = portIndex;
 
-                    err = mOMX->getParameter(
-                            mNode, OMX_IndexParamAudioAac, &params, sizeof(params));
+                    err = mOMXNode->getParameter(
+                            OMX_IndexParamAudioAac, &params, sizeof(params));
                     if (err != OK) {
                         return err;
                     }
@@ -4932,8 +4900,8 @@
                     InitOMXParams(&params);
                     params.nPortIndex = portIndex;
 
-                    err = mOMX->getParameter(
-                            mNode, OMX_IndexParamAudioAmr, &params, sizeof(params));
+                    err = mOMXNode->getParameter(
+                            OMX_IndexParamAudioAmr, &params, sizeof(params));
                     if (err != OK) {
                         return err;
                     }
@@ -4955,8 +4923,8 @@
                     InitOMXParams(&params);
                     params.nPortIndex = portIndex;
 
-                    err = mOMX->getParameter(
-                            mNode, OMX_IndexParamAudioFlac, &params, sizeof(params));
+                    err = mOMXNode->getParameter(
+                            OMX_IndexParamAudioFlac, &params, sizeof(params));
                     if (err != OK) {
                         return err;
                     }
@@ -4973,8 +4941,8 @@
                     InitOMXParams(&params);
                     params.nPortIndex = portIndex;
 
-                    err = mOMX->getParameter(
-                            mNode, OMX_IndexParamAudioMp3, &params, sizeof(params));
+                    err = mOMXNode->getParameter(
+                            OMX_IndexParamAudioMp3, &params, sizeof(params));
                     if (err != OK) {
                         return err;
                     }
@@ -4991,8 +4959,8 @@
                     InitOMXParams(&params);
                     params.nPortIndex = portIndex;
 
-                    err = mOMX->getParameter(
-                            mNode, OMX_IndexParamAudioVorbis, &params, sizeof(params));
+                    err = mOMXNode->getParameter(
+                            OMX_IndexParamAudioVorbis, &params, sizeof(params));
                     if (err != OK) {
                         return err;
                     }
@@ -5009,8 +4977,8 @@
                     InitOMXParams(&params);
                     params.nPortIndex = portIndex;
 
-                    err = mOMX->getParameter(
-                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
+                    err = mOMXNode->getParameter(
+                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
                             &params, sizeof(params));
                     if (err != OK) {
                         return err;
@@ -5028,8 +4996,8 @@
                     InitOMXParams(&params);
                     params.nPortIndex = portIndex;
 
-                    err = mOMX->getParameter(
-                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
+                    err = mOMXNode->getParameter(
+                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
                             &params, sizeof(params));
                     if (err != OK) {
                         return err;
@@ -5047,8 +5015,8 @@
                     InitOMXParams(&params);
                     params.nPortIndex = portIndex;
 
-                    err = mOMX->getParameter(
-                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
+                    err = mOMXNode->getParameter(
+                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
                             &params, sizeof(params));
                     if (err != OK) {
                         return err;
@@ -5066,8 +5034,8 @@
                     InitOMXParams(&params);
                     params.nPortIndex = portIndex;
 
-                    err = mOMX->getParameter(
-                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
+                    err = mOMXNode->getParameter(
+                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
                     if (err != OK) {
                         return err;
                     }
@@ -5093,8 +5061,8 @@
                     InitOMXParams(&params);
                     params.nPortIndex = portIndex;
 
-                    err = mOMX->getParameter(
-                                mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
+                    err = mOMXNode->getParameter(
+                                OMX_IndexParamAudioPcm, &params, sizeof(params));
                     if (err != OK) {
                         return err;
                     }
@@ -5278,8 +5246,7 @@
     params.nPortIndex = kPortIndexOutput;
     params.IntraRefreshVOP = OMX_TRUE;
 
-    return mOMX->setConfig(
-            mNode,
+    return mOMXNode->setConfig(
             OMX_IndexConfigVideoIntraVOPRefresh,
             &params,
             sizeof(params));
@@ -5400,7 +5367,7 @@
         {
             ALOGI("[%s] forcing the release of codec",
                     mCodec->mComponentName.c_str());
-            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
+            status_t err = mCodec->mOMXNode->freeNode();
             ALOGE_IF("[%s] failed to release codec instance: err=%d",
                        mCodec->mComponentName.c_str(), err);
             sp<AMessage> notify = mCodec->mNotify->dup();
@@ -5419,16 +5386,17 @@
 bool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
     // there is a possibility that this is an outstanding message for a
     // codec that we have already destroyed
-    if (mCodec->mNode == 0) {
+    if (mCodec->mOMXNode == NULL) {
         ALOGI("ignoring message as already freed component: %s",
                 msg->debugString().c_str());
         return false;
     }
 
-    IOMX::node_id nodeID;
-    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
-    if (nodeID != mCodec->mNode) {
-        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
+    int32_t generation;
+    CHECK(msg->findInt32("generation", (int32_t*)&generation));
+    if (generation != mCodec->mNodeGeneration) {
+        ALOGW("Unexpected message for component: %s, gen %u, cur %u",
+                msg->debugString().c_str(), generation, mCodec->mNodeGeneration);
         return false;
     }
     return true;
@@ -5795,8 +5763,8 @@
                     if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) {
                         VideoNativeHandleMetadata *vnhmd =
                             (VideoNativeHandleMetadata*)info->mCodecData->base();
-                        err2 = mCodec->mOMX->updateNativeHandleInMeta(
-                                mCodec->mNode, kPortIndexInput,
+                        err2 = mCodec->mOMXNode->updateNativeHandleInMeta(
+                                mCodec->kPortIndexInput,
                                 NativeHandle::create(vnhmd->pHandle, false /* ownsHandle */),
                                 bufferID);
                     }
@@ -5804,8 +5772,8 @@
                 case kMetadataBufferTypeANWBuffer:
                     if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
                         VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base();
-                        err2 = mCodec->mOMX->updateGraphicBufferInMeta(
-                                mCodec->mNode, kPortIndexInput,
+                        err2 = mCodec->mOMXNode->updateGraphicBufferInMeta(
+                                mCodec->kPortIndexInput,
                                 new GraphicBuffer(vnmd->pBuffer, false /* keepOwnership */),
                                 bufferID);
                     }
@@ -5820,8 +5788,7 @@
                 }
 
                 if (err2 == OK) {
-                    err2 = mCodec->mOMX->emptyBuffer(
-                        mCodec->mNode,
+                    err2 = mCodec->mOMXNode->emptyBuffer(
                         bufferID,
                         0,
                         info->mCodecData->size(),
@@ -5858,8 +5825,7 @@
                      mCodec->mComponentName.c_str(), bufferID);
 
                 info->checkReadFence("onInputBufferFilled");
-                status_t err2 = mCodec->mOMX->emptyBuffer(
-                        mCodec->mNode,
+                status_t err2 = mCodec->mOMXNode->emptyBuffer(
                         bufferID,
                         0,
                         0,
@@ -5989,7 +5955,7 @@
                 ALOGV("[%s] calling fillBuffer %u",
                      mCodec->mComponentName.c_str(), info->mBufferID);
 
-                err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
+                err = mCodec->mOMXNode->fillBuffer(info->mBufferID, info->mFenceFd);
                 info->mFenceFd = -1;
                 if (err != OK) {
                     mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
@@ -6217,8 +6183,8 @@
                     ALOGV("[%s] calling fillBuffer %u",
                          mCodec->mComponentName.c_str(), info->mBufferID);
                     info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
-                    status_t err = mCodec->mOMX->fillBuffer(
-                            mCodec->mNode, info->mBufferID, info->mFenceFd);
+                    status_t err = mCodec->mOMXNode->fillBuffer(
+                            info->mBufferID, info->mFenceFd);
                     info->mFenceFd = -1;
                     if (err == OK) {
                         info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
@@ -6262,8 +6228,8 @@
     mCodec->mUsingNativeWindow = false;
     mCodec->mNativeWindow.clear();
     mCodec->mNativeWindowUsageBits = 0;
-    mCodec->mNode = 0;
     mCodec->mOMX.clear();
+    mCodec->mOMXNode.clear();
     mCodec->mQuirks = 0;
     mCodec->mFlags = 0;
     mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
@@ -6343,7 +6309,7 @@
 bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
     ALOGV("onAllocateComponent");
 
-    CHECK(mCodec->mNode == 0);
+    CHECK(mCodec->mOMXNode == NULL);
 
     OMXClient client;
     if (client.connect() != OK) {
@@ -6382,7 +6348,7 @@
     }
 
     sp<CodecObserver> observer = new CodecObserver;
-    IOMX::node_id node = 0;
+    sp<IOMXNode> omxNode;
 
     status_t err = NAME_NOT_FOUND;
     for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
@@ -6393,7 +6359,7 @@
         pid_t tid = gettid();
         int prevPriority = androidGetThreadPriority(tid);
         androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
-        err = omx->allocateNode(componentName.c_str(), observer, &mCodec->mNodeBinder, &node);
+        err = omx->allocateNode(componentName.c_str(), observer, &mCodec->mNodeBinder, &omxNode);
         androidSetThreadPriority(tid, prevPriority);
 
         if (err == OK) {
@@ -6402,10 +6368,10 @@
             ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
         }
 
-        node = 0;
+        omxNode = NULL;
     }
 
-    if (node == 0) {
+    if (omxNode == NULL) {
         if (!mime.empty()) {
             ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
                     encoder ? "en" : "de", mime.c_str(), err);
@@ -6426,6 +6392,7 @@
     }
 
     notify = new AMessage(kWhatOMXMessageList, mCodec);
+    notify->setInt32("generation", ++mCodec->mNodeGeneration);
     observer->setNotificationMessage(notify);
 
     mCodec->mComponentName = componentName;
@@ -6440,7 +6407,7 @@
 
     mCodec->mQuirks = quirks;
     mCodec->mOMX = omx;
-    mCodec->mNode = node;
+    mCodec->mOMXNode = omxNode;
 
     {
         sp<AMessage> notify = mCodec->mNotify->dup();
@@ -6491,7 +6458,7 @@
 
 void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
     if (!keepComponentAllocated) {
-        (void)mCodec->mOMX->freeNode(mCodec->mNode);
+        (void)mCodec->mOMXNode->freeNode();
 
         mCodec->changeState(mCodec->mUninitializedState);
     }
@@ -6570,7 +6537,7 @@
         const sp<AMessage> &msg) {
     ALOGV("onConfigureComponent");
 
-    CHECK(mCodec->mNode != 0);
+    CHECK(mCodec->mOMXNode != NULL);
 
     status_t err = OK;
     AString mime;
@@ -6662,8 +6629,8 @@
     }
 
     uint32_t usageBits;
-    if (mCodec->mOMX->getParameter(
-            mCodec->mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
+    if (mCodec->mOMXNode->getParameter(
+            (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
             &usageBits, sizeof(usageBits)) == OK) {
         mCodec->mInputFormat->setInt32(
                 "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
@@ -6704,8 +6671,8 @@
     sp<IGraphicBufferProducer> bufferProducer;
     if (err == OK) {
         mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
-        err = mCodec->mOMX->createInputSurface(
-                mCodec->mNode, kPortIndexInput, dataSpace,
+        err = mCodec->mOMXNode->createInputSurface(
+                mCodec->kPortIndexInput, dataSpace,
                 &bufferProducer, &mCodec->mGraphicBufferSource,
                 &mCodec->mInputMetadataType);
         // framework uses ANW buffers internally instead of gralloc handles
@@ -6751,8 +6718,8 @@
 
     if (err == OK) {
         mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
-        err = mCodec->mOMX->setInputSurface(
-                mCodec->mNode, kPortIndexInput,
+        err = mCodec->mOMXNode->setInputSurface(
+                mCodec->kPortIndexInput,
                 surface->getBufferConsumer(),
                 &mCodec->mGraphicBufferSource,
                 &mCodec->mInputMetadataType);
@@ -6781,7 +6748,7 @@
 void ACodec::LoadedState::onStart() {
     ALOGV("onStart");
 
-    status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
+    status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
     if (err != OK) {
         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
     } else {
@@ -6806,8 +6773,8 @@
 
         mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
 
-        mCodec->mOMX->sendCommand(
-                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
+        mCodec->mOMXNode->sendCommand(
+                OMX_CommandStateSet, OMX_StateLoaded);
         if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
             mCodec->freeBuffersOnPort(kPortIndexInput);
         }
@@ -6879,8 +6846,8 @@
             }
 
             if (err == OK) {
-                err = mCodec->mOMX->sendCommand(
-                    mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting);
+                err = mCodec->mOMXNode->sendCommand(
+                    OMX_CommandStateSet, OMX_StateExecuting);
             }
 
             if (err != OK) {
@@ -7023,7 +6990,7 @@
         ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
 
         info->checkWriteFence("submitRegularOutputBuffers");
-        status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
+        status_t err = mCodec->mOMXNode->fillBuffer(info->mBufferID, info->mFenceFd);
         info->mFenceFd = -1;
         if (err != OK) {
             failed = true;
@@ -7091,8 +7058,8 @@
 
             mActive = false;
 
-            status_t err = mCodec->mOMX->sendCommand(
-                    mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
+            status_t err = mCodec->mOMXNode->sendCommand(
+                    OMX_CommandStateSet, OMX_StateIdle);
             if (err != OK) {
                 if (keepComponentAllocated) {
                     mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
@@ -7118,7 +7085,7 @@
 
             mActive = false;
 
-            status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL);
+            status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL);
             if (err != OK) {
                 mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
             } else {
@@ -7201,8 +7168,7 @@
         configParams.nPortIndex = kPortIndexOutput;
         configParams.nEncodeBitrate = videoBitrate;
 
-        status_t err = mOMX->setConfig(
-                mNode,
+        status_t err = mOMXNode->setConfig(
                 OMX_IndexConfigVideoBitrate,
                 &configParams,
                 sizeof(configParams));
@@ -7336,8 +7302,7 @@
 
             if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
                 mCodec->mMetadataBuffersToSubmit = 0;
-                CHECK_EQ(mCodec->mOMX->sendCommand(
-                            mCodec->mNode,
+                CHECK_EQ(mCodec->mOMXNode->sendCommand(
                             OMX_CommandPortDisable, kPortIndexOutput),
                          (status_t)OK);
 
@@ -7442,8 +7407,8 @@
                 }
 
                 if (err == OK) {
-                    err = mCodec->mOMX->sendCommand(
-                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput);
+                    err = mCodec->mOMXNode->sendCommand(
+                            OMX_CommandPortEnable, kPortIndexOutput);
                 }
 
                 if (err == OK) {
@@ -7568,8 +7533,8 @@
 
 void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
     if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
-        status_t err = mCodec->mOMX->sendCommand(
-                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
+        status_t err = mCodec->mOMXNode->sendCommand(
+                OMX_CommandStateSet, OMX_StateLoaded);
         if (err == OK) {
             err = mCodec->freeBuffersOnPort(kPortIndexInput);
             status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
@@ -7755,7 +7720,7 @@
         {
             sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
             msg->setInt32("type", omx_message::EVENT);
-            msg->setInt32("node", mCodec->mNode);
+            msg->setInt32("generation", mCodec->mNodeGeneration);
             msg->setInt32("event", event);
             msg->setInt32("data1", data1);
             msg->setInt32("data2", data2);
@@ -7831,17 +7796,17 @@
 
     sp<IOMX> omx = client.interface();
     sp<CodecObserver> observer = new CodecObserver;
-    IOMX::node_id node = 0;
+    sp<IOMXNode> omxNode;
 
-    err = omx->allocateNode(name.c_str(), observer, NULL, &node);
+    err = omx->allocateNode(name.c_str(), observer, NULL, &omxNode);
     if (err != OK) {
         client.disconnect();
         return err;
     }
 
-    err = SetComponentRole(omx, node, role);
+    err = SetComponentRole(omxNode, role);
     if (err != OK) {
-        omx->freeNode(node);
+        omxNode->freeNode();
         client.disconnect();
         return err;
     }
@@ -7856,8 +7821,8 @@
 
         for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
             param.nProfileIndex = index;
-            status_t err = omx->getParameter(
-                    node, OMX_IndexParamVideoProfileLevelQuerySupported,
+            status_t err = omxNode->getParameter(
+                    OMX_IndexParamVideoProfileLevelQuerySupported,
                     &param, sizeof(param));
             if (err != OK) {
                 break;
@@ -7880,8 +7845,8 @@
         Vector<uint32_t> supportedColors; // shadow copy to check for duplicates
         for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
             portFormat.nIndex = index;
-            status_t err = omx->getParameter(
-                    node, OMX_IndexParamVideoPortFormat,
+            status_t err = omxNode->getParameter(
+                    OMX_IndexParamVideoPortFormat,
                     &portFormat, sizeof(portFormat));
             if (err != OK) {
                 break;
@@ -7889,7 +7854,7 @@
 
             OMX_U32 flexibleEquivalent;
             if (IsFlexibleColorFormat(
-                    omx, node, portFormat.eColorFormat, false /* usingNativeWindow */,
+                    omxNode, portFormat.eColorFormat, false /* usingNativeWindow */,
                     &flexibleEquivalent)) {
                 bool marked = false;
                 for (size_t i = 0; i < supportedColors.size(); ++i) {
@@ -7919,8 +7884,8 @@
         param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
         for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
             param.nProfileIndex = index;
-            status_t err = omx->getParameter(
-                    node, (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
+            status_t err = omxNode->getParameter(
+                    (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
                     &param, sizeof(param));
             if (err != OK) {
                 break;
@@ -7944,15 +7909,15 @@
 
     if (isVideo && !isEncoder) {
         native_handle_t *sidebandHandle = NULL;
-        if (omx->configureVideoTunnelMode(
-                node, kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
+        if (omxNode->configureVideoTunnelMode(
+                kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
             // tunneled playback includes adaptive playback
             builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
                     | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
-        } else if (omx->storeMetaDataInBuffers(
-                node, kPortIndexOutput, OMX_TRUE) == OK ||
-            omx->prepareForAdaptivePlayback(
-                node, kPortIndexOutput, OMX_TRUE,
+        } else if (omxNode->storeMetaDataInBuffers(
+                kPortIndexOutput, OMX_TRUE) == OK ||
+                omxNode->prepareForAdaptivePlayback(
+                kPortIndexOutput, OMX_TRUE,
                 1280 /* width */, 720 /* height */) == OK) {
             builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
         }
@@ -7963,15 +7928,15 @@
         InitOMXParams(&params);
         params.nPortIndex = kPortIndexOutput;
         // TODO: should we verify if fallback is supported?
-        if (omx->getConfig(
-                node, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
+        if (omxNode->getConfig(
+                (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
                 &params, sizeof(params)) == OK) {
             builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
         }
     }
 
     *caps = builder;
-    omx->freeNode(node);
+    omxNode->freeNode();
     client.disconnect();
     return OK;
 }
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 8afb7e9..1f869b1 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -196,9 +196,7 @@
     if (mInitCheck != OK) {
         return;  // this may fail if IMediaPlayerService is not available.
     }
-    mOMX = client.interface();
     parseXMLFile(codecs_xml);
-    mOMX.clear();
 
     if (mInitCheck != OK) {
         if (ignore_errors) {
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index 05ad2e8..a29aff0 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -24,513 +24,18 @@
 #include <utils/Log.h>
 
 #include <binder/IServiceManager.h>
-#include <media/IMediaPlayerService.h>
 #include <media/IMediaCodecService.h>
-#include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/OMXClient.h>
-#include <cutils/properties.h>
-#include <utils/KeyedVector.h>
 
 #include "include/OMX.h"
 
 namespace android {
 
-static bool sCodecProcessEnabled = true;
-
-struct MuxOMX : public IOMX {
-    MuxOMX(const sp<IOMX> &mediaServerOMX, const sp<IOMX> &mediaCodecOMX);
-    virtual ~MuxOMX();
-
-    // Nobody should be calling this. In case someone does anyway, just
-    // return the media server IOMX.
-    // TODO: return NULL
-    virtual IBinder *onAsBinder() {
-        ALOGE("MuxOMX::onAsBinder should not be called");
-        return IInterface::asBinder(mMediaServerOMX).get();
-    }
-
-    virtual bool livesLocally(node_id node, pid_t pid);
-
-    virtual status_t listNodes(List<ComponentInfo> *list);
-
-    virtual status_t allocateNode(
-            const char *name, const sp<IOMXObserver> &observer,
-            sp<IBinder> *nodeBinder,
-            node_id *node);
-
-    virtual status_t freeNode(node_id node);
-
-    virtual status_t sendCommand(
-            node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param);
-
-    virtual status_t getParameter(
-            node_id node, OMX_INDEXTYPE index,
-            void *params, size_t size);
-
-    virtual status_t setParameter(
-            node_id node, OMX_INDEXTYPE index,
-            const void *params, size_t size);
-
-    virtual status_t getConfig(
-            node_id node, OMX_INDEXTYPE index,
-            void *params, size_t size);
-
-    virtual status_t setConfig(
-            node_id node, OMX_INDEXTYPE index,
-            const void *params, size_t size);
-
-    virtual status_t getState(
-            node_id node, OMX_STATETYPE* state);
-
-    virtual status_t storeMetaDataInBuffers(
-            node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type);
-
-    virtual status_t prepareForAdaptivePlayback(
-            node_id node, OMX_U32 port_index, OMX_BOOL enable,
-            OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight);
-
-    virtual status_t configureVideoTunnelMode(
-            node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
-            OMX_U32 audioHwSync, native_handle_t **sidebandHandle);
-
-    virtual status_t enableNativeBuffers(
-            node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable);
-
-    virtual status_t getGraphicBufferUsage(
-            node_id node, OMX_U32 port_index, OMX_U32* usage);
-
-    virtual status_t useBuffer(
-            node_id node, OMX_U32 port_index, const sp<IMemory> &params,
-            buffer_id *buffer, OMX_U32 allottedSize);
-
-    virtual status_t useGraphicBuffer(
-            node_id node, OMX_U32 port_index,
-            const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer);
-
-    virtual status_t updateGraphicBufferInMeta(
-            node_id node, OMX_U32 port_index,
-            const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer);
-
-    virtual status_t updateNativeHandleInMeta(
-            node_id node, OMX_U32 port_index,
-            const sp<NativeHandle> &nativeHandle, buffer_id buffer);
-
-    virtual status_t createInputSurface(
-            node_id node, OMX_U32 port_index, android_dataspace dataSpace,
-            sp<IGraphicBufferProducer> *bufferProducer,
-            sp<IGraphicBufferSource> *bufferSource,
-            MetadataBufferType *type);
-
-    virtual status_t createPersistentInputSurface(
-            sp<IGraphicBufferProducer> *bufferProducer,
-            sp<IGraphicBufferConsumer> *bufferConsumer);
-
-    virtual status_t setInputSurface(
-            node_id node, OMX_U32 port_index,
-            const sp<IGraphicBufferConsumer> &bufferConsumer,
-            sp<IGraphicBufferSource> *bufferSource,
-            MetadataBufferType *type);
-
-    virtual status_t allocateSecureBuffer(
-            node_id node, OMX_U32 port_index, size_t size,
-            buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle);
-
-    virtual status_t allocateBufferWithBackup(
-            node_id node, OMX_U32 port_index, const sp<IMemory> &params,
-            buffer_id *buffer, OMX_U32 allottedSize);
-
-    virtual status_t freeBuffer(
-            node_id node, OMX_U32 port_index, buffer_id buffer);
-
-    virtual status_t fillBuffer(node_id node, buffer_id buffer, int fenceFd);
-
-    virtual status_t emptyBuffer(
-            node_id node,
-            buffer_id buffer,
-            OMX_U32 range_offset, OMX_U32 range_length,
-            OMX_U32 flags, OMX_TICKS timestamp, int fenceFd);
-
-    virtual status_t emptyGraphicBuffer(
-            node_id node,
-            buffer_id buffer,
-            const sp<GraphicBuffer> &graphicBuffer, OMX_U32 flags,
-            OMX_TICKS timestamp, OMX_TICKS origTimestamp, int fenceFd);
-
-    virtual status_t getExtensionIndex(
-            node_id node,
-            const char *parameter_name,
-            OMX_INDEXTYPE *index);
-
-    virtual status_t dispatchMessage(const omx_message &msg);
-
-private:
-    mutable Mutex mLock;
-
-    sp<IOMX> mMediaServerOMX;
-    sp<IOMX> mMediaCodecOMX;
-    sp<IOMX> mLocalOMX;
-
-    typedef enum {
-        LOCAL,
-        MEDIAPROCESS,
-        CODECPROCESS
-    } node_location;
-
-    KeyedVector<node_id, node_location> mNodeLocation;
-
-    bool isLocalNode(node_id node) const;
-    bool isLocalNode_l(node_id node) const;
-    const sp<IOMX> &getOMX(node_id node) const;
-    const sp<IOMX> &getOMX_l(node_id node) const;
-
-    static node_location getPreferredCodecLocation(const char *name);
-
-    DISALLOW_EVIL_CONSTRUCTORS(MuxOMX);
-};
-
-MuxOMX::MuxOMX(const sp<IOMX> &mediaServerOMX, const sp<IOMX> &mediaCodecOMX)
-    : mMediaServerOMX(mediaServerOMX),
-      mMediaCodecOMX(mediaCodecOMX) {
-    ALOGI("MuxOMX ctor");
-}
-
-MuxOMX::~MuxOMX() {
-}
-
-bool MuxOMX::isLocalNode(node_id node) const {
-    Mutex::Autolock autoLock(mLock);
-
-    return isLocalNode_l(node);
-}
-
-bool MuxOMX::isLocalNode_l(node_id node) const {
-    return mNodeLocation.valueFor(node) == LOCAL;
-}
-
-// static
-MuxOMX::node_location MuxOMX::getPreferredCodecLocation(const char *name) {
-    if (sCodecProcessEnabled) {
-        // all codecs go to codec process unless excluded using system property, in which case
-        // all non-secure decoders, OMX.google.* codecs and encoders can go in the codec process
-        // (non-OMX.google.* encoders can be excluded using system property.)
-        if ((strcasestr(name, "decoder")
-                        && strcasestr(name, ".secure") != name + strlen(name) - 7)
-                || (strcasestr(name, "encoder")
-                        && !property_get_bool("media.stagefright.legacyencoder", false))
-                || !property_get_bool("media.stagefright.less-secure", false)
-                || !strncasecmp(name, "OMX.google.", 11)) {
-            return CODECPROCESS;
-        }
-        // everything else runs in the media server
-        return MEDIAPROCESS;
-    } else {
-#ifdef __LP64__
-        // 64 bit processes always run OMX remote on MediaServer
-        return MEDIAPROCESS;
-#else
-        // 32 bit processes run only OMX.google.* components locally
-        if (!strncasecmp(name, "OMX.google.", 11)) {
-            return LOCAL;
-        }
-        return MEDIAPROCESS;
-#endif
-    }
-}
-
-const sp<IOMX> &MuxOMX::getOMX(node_id node) const {
-    Mutex::Autolock autoLock(mLock);
-    return getOMX_l(node);
-}
-
-const sp<IOMX> &MuxOMX::getOMX_l(node_id node) const {
-    node_location loc = mNodeLocation.valueFor(node);
-    if (loc == LOCAL) {
-        return mLocalOMX;
-    } else if (loc == MEDIAPROCESS) {
-        return mMediaServerOMX;
-    } else if (loc == CODECPROCESS) {
-        return mMediaCodecOMX;
-    }
-    ALOGE("Couldn't determine node location for node %d: %d, using local", node, loc);
-    return mLocalOMX;
-}
-
-bool MuxOMX::livesLocally(node_id node, pid_t pid) {
-    return getOMX(node)->livesLocally(node, pid);
-}
-
-status_t MuxOMX::listNodes(List<ComponentInfo> *list) {
-    Mutex::Autolock autoLock(mLock);
-
-    if (mLocalOMX == NULL) {
-        mLocalOMX = new OMX;
-    }
-
-    return mLocalOMX->listNodes(list);
-}
-
-status_t MuxOMX::allocateNode(
-        const char *name, const sp<IOMXObserver> &observer,
-        sp<IBinder> *nodeBinder,
-        node_id *node) {
-    Mutex::Autolock autoLock(mLock);
-
-    sp<IOMX> omx;
-
-    node_location loc = getPreferredCodecLocation(name);
-    if (loc == CODECPROCESS) {
-        omx = mMediaCodecOMX;
-    } else if (loc == MEDIAPROCESS) {
-        omx = mMediaServerOMX;
-    } else {
-        if (mLocalOMX == NULL) {
-            mLocalOMX = new OMX;
-        }
-        omx = mLocalOMX;
-    }
-
-    status_t err = omx->allocateNode(name, observer, nodeBinder, node);
-    ALOGV("allocated node_id %x on %s OMX", *node, omx == mMediaCodecOMX ? "codecprocess" :
-            omx == mMediaServerOMX ? "mediaserver" : "local");
-
-
-    if (err != OK) {
-        return err;
-    }
-
-    mNodeLocation.add(*node, loc);
-
-    return OK;
-}
-
-status_t MuxOMX::freeNode(node_id node) {
-    Mutex::Autolock autoLock(mLock);
-
-    // exit if we have already freed the node
-    if (mNodeLocation.indexOfKey(node) < 0) {
-        ALOGD("MuxOMX::freeNode: node %d seems to be released already --- ignoring.", node);
-        return OK;
-    }
-
-    status_t err = getOMX_l(node)->freeNode(node);
-
-    if (err != OK) {
-        return err;
-    }
-
-    mNodeLocation.removeItem(node);
-
-    return OK;
-}
-
-status_t MuxOMX::sendCommand(
-        node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
-    return getOMX(node)->sendCommand(node, cmd, param);
-}
-
-status_t MuxOMX::getParameter(
-        node_id node, OMX_INDEXTYPE index,
-        void *params, size_t size) {
-    return getOMX(node)->getParameter(node, index, params, size);
-}
-
-status_t MuxOMX::setParameter(
-        node_id node, OMX_INDEXTYPE index,
-        const void *params, size_t size) {
-    return getOMX(node)->setParameter(node, index, params, size);
-}
-
-status_t MuxOMX::getConfig(
-        node_id node, OMX_INDEXTYPE index,
-        void *params, size_t size) {
-    return getOMX(node)->getConfig(node, index, params, size);
-}
-
-status_t MuxOMX::setConfig(
-        node_id node, OMX_INDEXTYPE index,
-        const void *params, size_t size) {
-    return getOMX(node)->setConfig(node, index, params, size);
-}
-
-status_t MuxOMX::getState(
-        node_id node, OMX_STATETYPE* state) {
-    return getOMX(node)->getState(node, state);
-}
-
-status_t MuxOMX::storeMetaDataInBuffers(
-        node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) {
-    return getOMX(node)->storeMetaDataInBuffers(node, port_index, enable, type);
-}
-
-status_t MuxOMX::prepareForAdaptivePlayback(
-        node_id node, OMX_U32 port_index, OMX_BOOL enable,
-        OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
-    return getOMX(node)->prepareForAdaptivePlayback(
-            node, port_index, enable, maxFrameWidth, maxFrameHeight);
-}
-
-status_t MuxOMX::configureVideoTunnelMode(
-        node_id node, OMX_U32 portIndex, OMX_BOOL enable,
-        OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
-    return getOMX(node)->configureVideoTunnelMode(
-            node, portIndex, enable, audioHwSync, sidebandHandle);
-}
-
-status_t MuxOMX::enableNativeBuffers(
-        node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
-    return getOMX(node)->enableNativeBuffers(node, port_index, graphic, enable);
-}
-
-status_t MuxOMX::getGraphicBufferUsage(
-        node_id node, OMX_U32 port_index, OMX_U32* usage) {
-    return getOMX(node)->getGraphicBufferUsage(node, port_index, usage);
-}
-
-status_t MuxOMX::useBuffer(
-        node_id node, OMX_U32 port_index, const sp<IMemory> &params,
-        buffer_id *buffer, OMX_U32 allottedSize) {
-    return getOMX(node)->useBuffer(node, port_index, params, buffer, allottedSize);
-}
-
-status_t MuxOMX::useGraphicBuffer(
-        node_id node, OMX_U32 port_index,
-        const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
-    return getOMX(node)->useGraphicBuffer(
-            node, port_index, graphicBuffer, buffer);
-}
-
-status_t MuxOMX::updateGraphicBufferInMeta(
-        node_id node, OMX_U32 port_index,
-        const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) {
-    return getOMX(node)->updateGraphicBufferInMeta(
-            node, port_index, graphicBuffer, buffer);
-}
-
-status_t MuxOMX::updateNativeHandleInMeta(
-        node_id node, OMX_U32 port_index,
-        const sp<NativeHandle> &nativeHandle, buffer_id buffer) {
-    return getOMX(node)->updateNativeHandleInMeta(
-            node, port_index, nativeHandle, buffer);
-}
-
-status_t MuxOMX::createInputSurface(
-        node_id node, OMX_U32 port_index, android_dataspace dataSpace,
-        sp<IGraphicBufferProducer> *bufferProducer,
-        sp<IGraphicBufferSource> *bufferSource,
-        MetadataBufferType *type) {
-    status_t err = getOMX(node)->createInputSurface(
-            node, port_index, dataSpace, bufferProducer, bufferSource, type);
-    return err;
-}
-
-status_t MuxOMX::createPersistentInputSurface(
-        sp<IGraphicBufferProducer> *bufferProducer,
-        sp<IGraphicBufferConsumer> *bufferConsumer) {
-    sp<IOMX> omx;
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (property_get_bool("media.stagefright.legacyencoder", false)) {
-            omx = mMediaServerOMX;
-        } else {
-            omx = mMediaCodecOMX;
-        }
-    }
-    return omx->createPersistentInputSurface(
-            bufferProducer, bufferConsumer);
-}
-
-status_t MuxOMX::setInputSurface(
-        node_id node, OMX_U32 port_index,
-        const sp<IGraphicBufferConsumer> &bufferConsumer,
-        sp<IGraphicBufferSource> *bufferSource,
-        MetadataBufferType *type) {
-    return getOMX(node)->setInputSurface(node, port_index, bufferConsumer, bufferSource, type);
-}
-
-status_t MuxOMX::allocateSecureBuffer(
-        node_id node, OMX_U32 port_index, size_t size,
-        buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle) {
-    return getOMX(node)->allocateSecureBuffer(
-            node, port_index, size, buffer, buffer_data, native_handle);
-}
-
-status_t MuxOMX::allocateBufferWithBackup(
-        node_id node, OMX_U32 port_index, const sp<IMemory> &params,
-        buffer_id *buffer, OMX_U32 allottedSize) {
-    return getOMX(node)->allocateBufferWithBackup(
-            node, port_index, params, buffer, allottedSize);
-}
-
-status_t MuxOMX::freeBuffer(
-        node_id node, OMX_U32 port_index, buffer_id buffer) {
-    return getOMX(node)->freeBuffer(node, port_index, buffer);
-}
-
-status_t MuxOMX::fillBuffer(node_id node, buffer_id buffer, int fenceFd) {
-    return getOMX(node)->fillBuffer(node, buffer, fenceFd);
-}
-
-status_t MuxOMX::emptyBuffer(
-        node_id node,
-        buffer_id buffer,
-        OMX_U32 range_offset, OMX_U32 range_length,
-        OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
-    return getOMX(node)->emptyBuffer(
-            node, buffer, range_offset, range_length, flags, timestamp, fenceFd);
-}
-
-status_t MuxOMX::emptyGraphicBuffer(
-        node_id node,
-        buffer_id buffer,
-        const sp<GraphicBuffer> &graphicBuffer, OMX_U32 flags,
-        OMX_TICKS timestamp, OMX_TICKS origTimestamp, int fenceFd) {
-    return getOMX(node)->emptyGraphicBuffer(
-            node, buffer, graphicBuffer, flags, timestamp, origTimestamp, fenceFd);
-}
-
-status_t MuxOMX::getExtensionIndex(
-        node_id node,
-        const char *parameter_name,
-        OMX_INDEXTYPE *index) {
-    return getOMX(node)->getExtensionIndex(node, parameter_name, index);
-}
-
-status_t MuxOMX::dispatchMessage(const omx_message &msg) {
-    return getOMX(msg.node)->dispatchMessage(msg);
-}
-
 OMXClient::OMXClient() {
-    char value[PROPERTY_VALUE_MAX];
-    if (property_get("media.stagefright.codecremote", value, NULL)
-            && (!strcmp("0", value) || !strcasecmp("false", value))) {
-        sCodecProcessEnabled = false;
-    }
 }
 
 status_t OMXClient::connect() {
     sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> playerbinder = sm->getService(String16("media.player"));
-    sp<IMediaPlayerService> mediaservice = interface_cast<IMediaPlayerService>(playerbinder);
-
-    if (mediaservice.get() == NULL) {
-        ALOGE("Cannot obtain IMediaPlayerService");
-        return NO_INIT;
-    }
-
-    sp<IOMX> mediaServerOMX = mediaservice->getOMX();
-    if (mediaServerOMX.get() == NULL) {
-        ALOGE("Cannot obtain mediaserver IOMX");
-        return NO_INIT;
-    }
-
-    // If we don't want to use the codec process, and the media server OMX
-    // is local, use it directly instead of going through MuxOMX
-    if (!sCodecProcessEnabled &&
-            mediaServerOMX->livesLocally(0 /* node */, getpid())) {
-        mOMX = mediaServerOMX;
-        return OK;
-    }
-
     sp<IBinder> codecbinder = sm->getService(String16("media.codec"));
     sp<IMediaCodecService> codecservice = interface_cast<IMediaCodecService>(codecbinder);
 
@@ -539,22 +44,17 @@
         return NO_INIT;
     }
 
-    sp<IOMX> mediaCodecOMX = codecservice->getOMX();
-    if (mediaCodecOMX.get() == NULL) {
+    mOMX = codecservice->getOMX();
+    if (mOMX.get() == NULL) {
         ALOGE("Cannot obtain mediacodec IOMX");
         return NO_INIT;
     }
 
-    mOMX = new MuxOMX(mediaServerOMX, mediaCodecOMX);
-
     return OK;
 }
 
 void OMXClient::disconnect() {
-    if (mOMX.get() != NULL) {
-        mOMX.clear();
-        mOMX = NULL;
-    }
+    mOMX.clear();
 }
 
 }  // namespace android
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index 3af59ae..1ef180f 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -31,159 +31,28 @@
 public:
     OMX();
 
-    virtual bool livesLocally(node_id node, pid_t pid);
-
     virtual status_t listNodes(List<ComponentInfo> *list);
 
     virtual status_t allocateNode(
             const char *name, const sp<IOMXObserver> &observer,
-            sp<IBinder> *nodeBinder,
-            node_id *node);
-
-    virtual status_t freeNode(node_id node);
-
-    virtual status_t sendCommand(
-            node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param);
-
-    virtual status_t getParameter(
-            node_id node, OMX_INDEXTYPE index,
-            void *params, size_t size);
-
-    virtual status_t setParameter(
-            node_id node, OMX_INDEXTYPE index,
-            const void *params, size_t size);
-
-    virtual status_t getConfig(
-            node_id node, OMX_INDEXTYPE index,
-            void *params, size_t size);
-
-    virtual status_t setConfig(
-            node_id node, OMX_INDEXTYPE index,
-            const void *params, size_t size);
-
-    virtual status_t getState(
-            node_id node, OMX_STATETYPE* state);
-
-    virtual status_t enableNativeBuffers(
-            node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable);
-
-    virtual status_t getGraphicBufferUsage(
-            node_id node, OMX_U32 port_index, OMX_U32* usage);
-
-    virtual status_t storeMetaDataInBuffers(
-            node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type);
-
-    virtual status_t prepareForAdaptivePlayback(
-            node_id node, OMX_U32 portIndex, OMX_BOOL enable,
-            OMX_U32 max_frame_width, OMX_U32 max_frame_height);
-
-    virtual status_t configureVideoTunnelMode(
-            node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
-            OMX_U32 audioHwSync, native_handle_t **sidebandHandle);
-
-    virtual status_t useBuffer(
-            node_id node, OMX_U32 port_index, const sp<IMemory> &params,
-            buffer_id *buffer, OMX_U32 allottedSize);
-
-    virtual status_t useGraphicBuffer(
-            node_id node, OMX_U32 port_index,
-            const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer);
-
-    virtual status_t updateGraphicBufferInMeta(
-            node_id node, OMX_U32 port_index,
-            const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer);
-
-    virtual status_t updateNativeHandleInMeta(
-            node_id node, OMX_U32 port_index,
-            const sp<NativeHandle> &nativeHandle, buffer_id buffer);
-
-    virtual status_t createInputSurface(
-            node_id node, OMX_U32 port_index, android_dataspace dataSpace,
-            sp<IGraphicBufferProducer> *bufferProducer,
-            sp<IGraphicBufferSource> *bufferSource,
-            MetadataBufferType *type);
+            sp<IBinder> *nodeBinder, sp<IOMXNode> *omxNode);
 
     virtual status_t createPersistentInputSurface(
             sp<IGraphicBufferProducer> *bufferProducer,
             sp<IGraphicBufferConsumer> *bufferConsumer);
 
-    virtual status_t setInputSurface(
-            node_id node, OMX_U32 port_index,
-            const sp<IGraphicBufferConsumer> &bufferConsumer,
-            sp<IGraphicBufferSource> *bufferSource,
-            MetadataBufferType *type);
-
-    virtual status_t allocateSecureBuffer(
-            node_id node, OMX_U32 port_index, size_t size,
-            buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle);
-
-    virtual status_t allocateBufferWithBackup(
-            node_id node, OMX_U32 port_index, const sp<IMemory> &params,
-            buffer_id *buffer, OMX_U32 allottedSize);
-
-    virtual status_t freeBuffer(
-            node_id node, OMX_U32 port_index, buffer_id buffer);
-
-    virtual status_t fillBuffer(node_id node, buffer_id buffer, int fenceFd);
-
-    virtual status_t emptyBuffer(
-            node_id node,
-            buffer_id buffer,
-            OMX_U32 range_offset, OMX_U32 range_length,
-            OMX_U32 flags, OMX_TICKS timestamp, int fenceFd);
-
-    virtual status_t emptyGraphicBuffer(
-            node_id node,
-            buffer_id buffer,
-            const sp<GraphicBuffer> &graphicBuffer, OMX_U32 flags,
-            OMX_TICKS timestamp, OMX_TICKS origTimestamp, int fenceFd);
-
-    virtual status_t getExtensionIndex(
-            node_id node,
-            const char *parameter_name,
-            OMX_INDEXTYPE *index);
-
-    virtual status_t dispatchMessage(const omx_message &msg);
-
     virtual void binderDied(const wp<IBinder> &the_late_who);
 
-    virtual bool isSecure(IOMX::node_id node);
-
-    OMX_ERRORTYPE OnEvent(
-            node_id node,
-            OMX_IN OMX_EVENTTYPE eEvent,
-            OMX_IN OMX_U32 nData1,
-            OMX_IN OMX_U32 nData2,
-            OMX_IN OMX_PTR pEventData);
-
-    OMX_ERRORTYPE OnEmptyBufferDone(
-            node_id node, buffer_id buffer, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer, int fenceFd);
-
-    OMX_ERRORTYPE OnFillBufferDone(
-            node_id node, buffer_id buffer, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer, int fenceFd);
-
-    void invalidateNodeID(node_id node);
+    status_t freeNode(const sp<OMXNodeInstance>& instance);
 
 protected:
     virtual ~OMX();
 
 private:
-    struct CallbackDispatcherThread;
-    struct CallbackDispatcher;
-
     Mutex mLock;
     OMXMaster *mMaster;
-    size_t mNodeCounter;
 
-    KeyedVector<wp<IBinder>, OMXNodeInstance *> mLiveNodes;
-    KeyedVector<node_id, OMXNodeInstance *> mNodeIDToInstance;
-    KeyedVector<node_id, sp<CallbackDispatcher> > mDispatchers;
-
-    node_id makeNodeID_l(OMXNodeInstance *instance);
-    OMXNodeInstance *findInstance(node_id node);
-    sp<CallbackDispatcher> findDispatcher(node_id node);
-
-    void invalidateNodeID_l(node_id node);
+    KeyedVector<wp<IBinder>, sp<OMXNodeInstance> > mLiveNodes;
 
     OMX(const OMX &);
     OMX &operator=(const OMX &);
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index e4f204e..79643d6 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -30,17 +30,16 @@
 class IOMXObserver;
 struct OMXMaster;
 
-struct OMXNodeInstance {
+struct OMXNodeInstance : public BnOMXNode {
     OMXNodeInstance(
             OMX *owner, const sp<IOMXObserver> &observer, const char *name);
 
-    void setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle);
+    void setHandle(OMX_HANDLETYPE handle);
 
-    OMX *owner();
+    OMX_HANDLETYPE handle();
     sp<IOMXObserver> observer();
-    OMX::node_id nodeID();
 
-    status_t freeNode(OMXMaster *master);
+    status_t freeNode() override;
 
     status_t sendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param);
     status_t getParameter(OMX_INDEXTYPE index, void *params, size_t size);
@@ -129,21 +128,25 @@
         return mIsSecure;
     }
 
+    status_t dispatchMessage(const omx_message &msg) override;
+
     // handles messages and removes them from the list
     void onMessages(std::list<omx_message> &messages);
-    void onObserverDied(OMXMaster *master);
-    void onGetHandleFailed();
+    void onObserverDied();
     void onEvent(OMX_EVENTTYPE event, OMX_U32 arg1, OMX_U32 arg2);
 
     static OMX_CALLBACKTYPE kCallbacks;
 
 private:
+    struct CallbackDispatcherThread;
+    struct CallbackDispatcher;
+
     Mutex mLock;
 
     OMX *mOwner;
-    OMX::node_id mNodeID;
     OMX_HANDLETYPE mHandle;
     sp<IOMXObserver> mObserver;
+    sp<CallbackDispatcher> mDispatcher;
     bool mDying;
     bool mSailed;  // configuration is set (no more meta-mode changes)
     bool mQueriedProhibitedExtensions;
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index 334c5d3..25bc41c 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -105,16 +105,14 @@
 }
 
 GraphicBufferSource::GraphicBufferSource(
-        const sp<IOMX> &omx,
-        IOMX::node_id nodeID,
+        const sp<IOMXNode> &omxNode,
         uint32_t bufferWidth,
         uint32_t bufferHeight,
         uint32_t bufferCount,
         uint32_t consumerUsage,
         const sp<IGraphicBufferConsumer> &consumer) :
     mInitCheck(UNKNOWN_ERROR),
-    mOMX(omx),
-    mNodeID(nodeID),
+    mOMXNode(omxNode),
     mExecuting(false),
     mSuspended(false),
     mLastDataSpace(HAL_DATASPACE_UNKNOWN),
@@ -427,14 +425,13 @@
     if (ColorUtils::convertDataSpaceToV0(dataSpace)) {
         omx_message msg;
         msg.type = omx_message::EVENT;
-        msg.node = mNodeID;
         msg.fenceFd = -1;
         msg.u.event_data.event = OMX_EventDataSpaceChanged;
         msg.u.event_data.data1 = mLastDataSpace;
         msg.u.event_data.data2 = ColorUtils::packToU32(mColorAspects);
         msg.u.event_data.data3 = pixelFormat;
 
-        mOMX->dispatchMessage(msg);
+        mOMXNode->dispatchMessage(msg);
     }
 }
 
@@ -702,8 +699,8 @@
     const sp<GraphicBuffer> &buffer = codecBuffer.mGraphicBuffer;
     int fenceID = item.mFence->isValid() ? item.mFence->dup() : -1;
 
-    status_t err = mOMX->emptyGraphicBuffer(
-            mNodeID, bufferID, buffer, OMX_BUFFERFLAG_ENDOFFRAME,
+    status_t err = mOMXNode->emptyGraphicBuffer(
+            bufferID, buffer, OMX_BUFFERFLAG_ENDOFFRAME,
             codecTimeUs, origTimeUs, fenceID);
 
     if (err != OK) {
@@ -736,8 +733,8 @@
     CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
     IOMX::buffer_id bufferID = codecBuffer.mBufferID;
 
-    status_t err = mOMX->emptyGraphicBuffer(
-            mNodeID, bufferID, NULL /* buffer */,
+    status_t err = mOMXNode->emptyGraphicBuffer(
+            bufferID, NULL /* buffer */,
             OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS,
             0 /* timestamp */, -1ll /* origTimestamp */, -1 /* fenceFd */);
     if (err != OK) {
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index 16fefc4..88fab02 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -59,8 +59,7 @@
                             public BufferQueue::ConsumerListener {
 public:
     GraphicBufferSource(
-            const sp<IOMX> &omx,
-            IOMX::node_id nodeID,
+            const sp<IOMXNode> &omxNode,
             uint32_t bufferWidth,
             uint32_t bufferHeight,
             uint32_t bufferCount,
@@ -261,9 +260,8 @@
     // Used to report constructor failure.
     status_t mInitCheck;
 
-    // Pointer back to the IOMX that created us.  We send buffers here.
-    sp<IOMX> mOMX;
-    IOMX::node_id mNodeID;
+    // Pointer back to the IOMXNode that created us.  We send buffers here.
+    sp<IOMXNode> mOMXNode;
 
     // Set by omxExecuting() / omxIdling().
     bool mExecuting;
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index d867fe4..81e03ba 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -26,149 +26,18 @@
 
 #include "../include/OMXNodeInstance.h"
 
-#include <binder/IMemory.h>
 #include <media/stagefright/foundation/ADebug.h>
-#include <utils/threads.h>
 
 #include "OMXMaster.h"
 #include "OMXUtils.h"
 
-#include <OMX_AsString.h>
-#include <OMX_Component.h>
-#include <OMX_VideoExt.h>
-
 namespace android {
 
 // node ids are created by concatenating the pid with a 16-bit counter
 static size_t kMaxNodeInstances = (1 << 16);
 
-////////////////////////////////////////////////////////////////////////////////
-
-// This provides the underlying Thread used by CallbackDispatcher.
-// Note that deriving CallbackDispatcher from Thread does not work.
-
-struct OMX::CallbackDispatcherThread : public Thread {
-    explicit CallbackDispatcherThread(CallbackDispatcher *dispatcher)
-        : mDispatcher(dispatcher) {
-    }
-
-private:
-    CallbackDispatcher *mDispatcher;
-
-    bool threadLoop();
-
-    CallbackDispatcherThread(const CallbackDispatcherThread &);
-    CallbackDispatcherThread &operator=(const CallbackDispatcherThread &);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct OMX::CallbackDispatcher : public RefBase {
-    explicit CallbackDispatcher(OMXNodeInstance *owner);
-
-    // Posts |msg| to the listener's queue. If |realTime| is true, the listener thread is notified
-    // that a new message is available on the queue. Otherwise, the message stays on the queue, but
-    // the listener is not notified of it. It will process this message when a subsequent message
-    // is posted with |realTime| set to true.
-    void post(const omx_message &msg, bool realTime = true);
-
-    bool loop();
-
-protected:
-    virtual ~CallbackDispatcher();
-
-private:
-    Mutex mLock;
-
-    OMXNodeInstance *mOwner;
-    bool mDone;
-    Condition mQueueChanged;
-    std::list<omx_message> mQueue;
-
-    sp<CallbackDispatcherThread> mThread;
-
-    void dispatch(std::list<omx_message> &messages);
-
-    CallbackDispatcher(const CallbackDispatcher &);
-    CallbackDispatcher &operator=(const CallbackDispatcher &);
-};
-
-OMX::CallbackDispatcher::CallbackDispatcher(OMXNodeInstance *owner)
-    : mOwner(owner),
-      mDone(false) {
-    mThread = new CallbackDispatcherThread(this);
-    mThread->run("OMXCallbackDisp", ANDROID_PRIORITY_FOREGROUND);
-}
-
-OMX::CallbackDispatcher::~CallbackDispatcher() {
-    {
-        Mutex::Autolock autoLock(mLock);
-
-        mDone = true;
-        mQueueChanged.signal();
-    }
-
-    // A join on self can happen if the last ref to CallbackDispatcher
-    // is released within the CallbackDispatcherThread loop
-    status_t status = mThread->join();
-    if (status != WOULD_BLOCK) {
-        // Other than join to self, the only other error return codes are
-        // whatever readyToRun() returns, and we don't override that
-        CHECK_EQ(status, (status_t)NO_ERROR);
-    }
-}
-
-void OMX::CallbackDispatcher::post(const omx_message &msg, bool realTime) {
-    Mutex::Autolock autoLock(mLock);
-
-    mQueue.push_back(msg);
-    if (realTime) {
-        mQueueChanged.signal();
-    }
-}
-
-void OMX::CallbackDispatcher::dispatch(std::list<omx_message> &messages) {
-    if (mOwner == NULL) {
-        ALOGV("Would have dispatched a message to a node that's already gone.");
-        return;
-    }
-    mOwner->onMessages(messages);
-}
-
-bool OMX::CallbackDispatcher::loop() {
-    for (;;) {
-        std::list<omx_message> messages;
-
-        {
-            Mutex::Autolock autoLock(mLock);
-            while (!mDone && mQueue.empty()) {
-                mQueueChanged.wait(mLock);
-            }
-
-            if (mDone) {
-                break;
-            }
-
-            messages.swap(mQueue);
-        }
-
-        dispatch(messages);
-    }
-
-    return false;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-bool OMX::CallbackDispatcherThread::threadLoop() {
-    return mDispatcher->loop();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
 OMX::OMX()
-    : mMaster(new OMXMaster),
-      mNodeCounter(0) {
+    : mMaster(new OMXMaster) {
 }
 
 OMX::~OMX() {
@@ -177,7 +46,7 @@
 }
 
 void OMX::binderDied(const wp<IBinder> &the_late_who) {
-    OMXNodeInstance *instance;
+    sp<OMXNodeInstance> instance;
 
     {
         Mutex::Autolock autoLock(mLock);
@@ -192,24 +61,9 @@
 
         instance = mLiveNodes.editValueAt(index);
         mLiveNodes.removeItemsAt(index);
-
-        index = mDispatchers.indexOfKey(instance->nodeID());
-        CHECK(index >= 0);
-        mDispatchers.removeItemsAt(index);
-
-        invalidateNodeID_l(instance->nodeID());
     }
 
-    instance->onObserverDied(mMaster);
-}
-
-bool OMX::isSecure(node_id node) {
-    OMXNodeInstance *instance = findInstance(node);
-    return (instance == NULL ? false : instance->isSecure());
-}
-
-bool OMX::livesLocally(node_id /* node */, pid_t pid) {
-    return pid == getpid();
+    instance->onObserverDied();
 }
 
 status_t OMX::listNodes(List<ComponentInfo> *list) {
@@ -242,48 +96,41 @@
 
 status_t OMX::allocateNode(
         const char *name, const sp<IOMXObserver> &observer,
-        sp<IBinder> *nodeBinder, node_id *node) {
+        sp<IBinder> *nodeBinder, sp<IOMXNode> *omxNode) {
     Mutex::Autolock autoLock(mLock);
 
-    *node = 0;
+    omxNode->clear();
     if (nodeBinder != NULL) {
         *nodeBinder = NULL;
     }
 
-    if (mNodeIDToInstance.size() == kMaxNodeInstances) {
-        // all possible node IDs are in use
+    if (mLiveNodes.size() == kMaxNodeInstances) {
         return NO_MEMORY;
     }
 
-    OMXNodeInstance *instance = new OMXNodeInstance(this, observer, name);
+    sp<OMXNodeInstance> instance = new OMXNodeInstance(this, observer, name);
 
     OMX_COMPONENTTYPE *handle;
     OMX_ERRORTYPE err = mMaster->makeComponentInstance(
             name, &OMXNodeInstance::kCallbacks,
-            instance, &handle);
+            instance.get(), &handle);
 
     if (err != OMX_ErrorNone) {
         ALOGE("FAILED to allocate omx component '%s' err=%s(%#x)", name, asString(err), err);
 
-        instance->onGetHandleFailed();
-
         return StatusFromOMXError(err);
     }
-
-    *node = makeNodeID_l(instance);
-    mDispatchers.add(*node, new CallbackDispatcher(instance));
-
-    instance->setHandle(*node, handle);
+    instance->setHandle(handle);
 
     mLiveNodes.add(IInterface::asBinder(observer), instance);
     IInterface::asBinder(observer)->linkToDeath(this);
 
+    *omxNode = instance;
+
     return OK;
 }
 
-status_t OMX::freeNode(node_id node) {
-    OMXNodeInstance *instance = findInstance(node);
-
+status_t OMX::freeNode(const sp<OMXNodeInstance> &instance) {
     if (instance == NULL) {
         return OK;
     }
@@ -301,219 +148,13 @@
 
     IInterface::asBinder(instance->observer())->unlinkToDeath(this);
 
-    status_t err = instance->freeNode(mMaster);
-
-    {
-        Mutex::Autolock autoLock(mLock);
-        ssize_t index = mDispatchers.indexOfKey(node);
-        CHECK(index >= 0);
-        mDispatchers.removeItemsAt(index);
+    OMX_ERRORTYPE err = OMX_ErrorNone;
+    if (instance->handle() != NULL) {
+        err = mMaster->destroyComponentInstance(
+                static_cast<OMX_COMPONENTTYPE *>(instance->handle()));
     }
 
-    return err;
-}
-
-status_t OMX::sendCommand(
-        node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->sendCommand(cmd, param);
-}
-
-status_t OMX::getParameter(
-        node_id node, OMX_INDEXTYPE index,
-        void *params, size_t size) {
-    ALOGV("getParameter(%u %#x %p %zd)", node, index, params, size);
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->getParameter(
-            index, params, size);
-}
-
-status_t OMX::setParameter(
-        node_id node, OMX_INDEXTYPE index,
-        const void *params, size_t size) {
-    ALOGV("setParameter(%u %#x %p %zd)", node, index, params, size);
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->setParameter(
-            index, params, size);
-}
-
-status_t OMX::getConfig(
-        node_id node, OMX_INDEXTYPE index,
-        void *params, size_t size) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->getConfig(
-            index, params, size);
-}
-
-status_t OMX::setConfig(
-        node_id node, OMX_INDEXTYPE index,
-        const void *params, size_t size) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->setConfig(
-            index, params, size);
-}
-
-status_t OMX::getState(
-        node_id node, OMX_STATETYPE* state) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->getState(
-            state);
-}
-
-status_t OMX::enableNativeBuffers(
-        node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->enableNativeBuffers(port_index, graphic, enable);
-}
-
-status_t OMX::getGraphicBufferUsage(
-        node_id node, OMX_U32 port_index, OMX_U32* usage) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->getGraphicBufferUsage(port_index, usage);
-}
-
-status_t OMX::storeMetaDataInBuffers(
-        node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->storeMetaDataInBuffers(port_index, enable, type);
-}
-
-status_t OMX::prepareForAdaptivePlayback(
-        node_id node, OMX_U32 portIndex, OMX_BOOL enable,
-        OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->prepareForAdaptivePlayback(
-            portIndex, enable, maxFrameWidth, maxFrameHeight);
-}
-
-status_t OMX::configureVideoTunnelMode(
-        node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
-        OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->configureVideoTunnelMode(
-            portIndex, tunneled, audioHwSync, sidebandHandle);
-}
-
-status_t OMX::useBuffer(
-        node_id node, OMX_U32 port_index, const sp<IMemory> &params,
-        buffer_id *buffer, OMX_U32 allottedSize) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->useBuffer(
-            port_index, params, buffer, allottedSize);
-}
-
-status_t OMX::useGraphicBuffer(
-        node_id node, OMX_U32 port_index,
-        const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->useGraphicBuffer(
-            port_index, graphicBuffer, buffer);
-}
-
-status_t OMX::updateGraphicBufferInMeta(
-        node_id node, OMX_U32 port_index,
-        const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->updateGraphicBufferInMeta(
-            port_index, graphicBuffer, buffer);
-}
-
-status_t OMX::updateNativeHandleInMeta(
-        node_id node, OMX_U32 port_index,
-        const sp<NativeHandle> &nativeHandle, buffer_id buffer) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->updateNativeHandleInMeta(
-            port_index, nativeHandle, buffer);
-}
-
-status_t OMX::createInputSurface(
-        node_id node, OMX_U32 port_index, android_dataspace dataSpace,
-        sp<IGraphicBufferProducer> *bufferProducer,
-        sp<IGraphicBufferSource> *bufferSource,
-        MetadataBufferType *type) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->createInputSurface(
-            port_index, dataSpace, bufferProducer, bufferSource, type);
+    return StatusFromOMXError(err);
 }
 
 status_t OMX::createPersistentInputSurface(
@@ -523,249 +164,4 @@
             bufferProducer, bufferConsumer);
 }
 
-status_t OMX::setInputSurface(
-        node_id node, OMX_U32 port_index,
-        const sp<IGraphicBufferConsumer> &bufferConsumer,
-        sp<IGraphicBufferSource> *bufferSource,
-        MetadataBufferType *type) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->setInputSurface(port_index, bufferConsumer, bufferSource, type);
-}
-
-status_t OMX::allocateSecureBuffer(
-        node_id node, OMX_U32 port_index, size_t size,
-        buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->allocateSecureBuffer(
-            port_index, size, buffer, buffer_data, native_handle);
-}
-
-status_t OMX::allocateBufferWithBackup(
-        node_id node, OMX_U32 port_index, const sp<IMemory> &params,
-        buffer_id *buffer, OMX_U32 allottedSize) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->allocateBufferWithBackup(
-            port_index, params, buffer, allottedSize);
-}
-
-status_t OMX::freeBuffer(node_id node, OMX_U32 port_index, buffer_id buffer) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->freeBuffer(
-            port_index, buffer);
-}
-
-status_t OMX::fillBuffer(node_id node, buffer_id buffer, int fenceFd) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->fillBuffer(buffer, fenceFd);
-}
-
-status_t OMX::emptyBuffer(
-        node_id node,
-        buffer_id buffer,
-        OMX_U32 range_offset, OMX_U32 range_length,
-        OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->emptyBuffer(
-            buffer, range_offset, range_length, flags, timestamp, fenceFd);
-}
-
-status_t OMX::emptyGraphicBuffer(
-        node_id node,
-        buffer_id buffer,
-        const sp<GraphicBuffer> &graphicBuffer, OMX_U32 flags,
-        OMX_TICKS timestamp, OMX_TICKS origTimestamp, int fenceFd) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->emptyGraphicBuffer(
-            buffer, graphicBuffer, flags, timestamp, origTimestamp, fenceFd);
-}
-
-status_t OMX::getExtensionIndex(
-        node_id node,
-        const char *parameter_name,
-        OMX_INDEXTYPE *index) {
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return NAME_NOT_FOUND;
-    }
-
-    return instance->getExtensionIndex(
-            parameter_name, index);
-}
-
-status_t OMX::dispatchMessage(const omx_message &msg) {
-    sp<OMX::CallbackDispatcher> dispatcher = findDispatcher(msg.node);
-
-    if (dispatcher == NULL) {
-        return OMX_ErrorComponentNotFound;
-    }
-
-    dispatcher->post(msg, true /*realTime*/);
-
-    return OMX_ErrorNone;
-}
-
-OMX_ERRORTYPE OMX::OnEvent(
-        node_id node,
-        OMX_IN OMX_EVENTTYPE eEvent,
-        OMX_IN OMX_U32 nData1,
-        OMX_IN OMX_U32 nData2,
-        OMX_IN OMX_PTR pEventData) {
-    ALOGV("OnEvent(%d, %" PRIu32", %" PRIu32 ")", eEvent, nData1, nData2);
-    OMXNodeInstance *instance = findInstance(node);
-
-    if (instance == NULL) {
-        return OMX_ErrorComponentNotFound;
-    }
-
-    // Forward to OMXNodeInstance.
-    instance->onEvent(eEvent, nData1, nData2);
-
-    sp<OMX::CallbackDispatcher> dispatcher = findDispatcher(node);
-
-    // output rendered events are not processed as regular events until they hit the observer
-    if (eEvent == OMX_EventOutputRendered) {
-        if (pEventData == NULL) {
-            return OMX_ErrorBadParameter;
-        }
-
-        // process data from array
-        OMX_VIDEO_RENDEREVENTTYPE *renderData = (OMX_VIDEO_RENDEREVENTTYPE *)pEventData;
-        for (size_t i = 0; i < nData1; ++i) {
-            omx_message msg;
-            msg.type = omx_message::FRAME_RENDERED;
-            msg.node = node;
-            msg.fenceFd = -1;
-            msg.u.render_data.timestamp = renderData[i].nMediaTimeUs;
-            msg.u.render_data.nanoTime = renderData[i].nSystemTimeNs;
-
-            dispatcher->post(msg, false /* realTime */);
-        }
-        return OMX_ErrorNone;
-    }
-
-    omx_message msg;
-    msg.type = omx_message::EVENT;
-    msg.node = node;
-    msg.fenceFd = -1;
-    msg.u.event_data.event = eEvent;
-    msg.u.event_data.data1 = nData1;
-    msg.u.event_data.data2 = nData2;
-
-    dispatcher->post(msg, true /* realTime */);
-
-    return OMX_ErrorNone;
-}
-
-OMX_ERRORTYPE OMX::OnEmptyBufferDone(
-        node_id node, buffer_id buffer, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer, int fenceFd) {
-    ALOGV("OnEmptyBufferDone buffer=%p", pBuffer);
-
-    omx_message msg;
-    msg.type = omx_message::EMPTY_BUFFER_DONE;
-    msg.node = node;
-    msg.fenceFd = fenceFd;
-    msg.u.buffer_data.buffer = buffer;
-
-    findDispatcher(node)->post(msg);
-
-    return OMX_ErrorNone;
-}
-
-OMX_ERRORTYPE OMX::OnFillBufferDone(
-        node_id node, buffer_id buffer, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer, int fenceFd) {
-    ALOGV("OnFillBufferDone buffer=%p", pBuffer);
-
-    omx_message msg;
-    msg.type = omx_message::FILL_BUFFER_DONE;
-    msg.node = node;
-    msg.fenceFd = fenceFd;
-    msg.u.extended_buffer_data.buffer = buffer;
-    msg.u.extended_buffer_data.range_offset = pBuffer->nOffset;
-    msg.u.extended_buffer_data.range_length = pBuffer->nFilledLen;
-    msg.u.extended_buffer_data.flags = pBuffer->nFlags;
-    msg.u.extended_buffer_data.timestamp = pBuffer->nTimeStamp;
-
-    findDispatcher(node)->post(msg);
-
-    return OMX_ErrorNone;
-}
-
-OMX::node_id OMX::makeNodeID_l(OMXNodeInstance *instance) {
-    // mLock is already held.
-
-    node_id prefix = node_id(getpid() << 16);
-    node_id node = 0;
-    do  {
-        if (++mNodeCounter >= kMaxNodeInstances) {
-            mNodeCounter = 0; // OK to use because we're combining with the pid
-        }
-        node = node_id(prefix | mNodeCounter);
-    } while (mNodeIDToInstance.indexOfKey(node) >= 0);
-    mNodeIDToInstance.add(node, instance);
-
-    return node;
-}
-
-OMXNodeInstance *OMX::findInstance(node_id node) {
-    Mutex::Autolock autoLock(mLock);
-
-    ssize_t index = mNodeIDToInstance.indexOfKey(node);
-
-    return index < 0 ? NULL : mNodeIDToInstance.valueAt(index);
-}
-
-sp<OMX::CallbackDispatcher> OMX::findDispatcher(node_id node) {
-    Mutex::Autolock autoLock(mLock);
-
-    ssize_t index = mDispatchers.indexOfKey(node);
-
-    return index < 0 ? NULL : mDispatchers.valueAt(index);
-}
-
-void OMX::invalidateNodeID(node_id node) {
-    Mutex::Autolock autoLock(mLock);
-    invalidateNodeID_l(node);
-}
-
-void OMX::invalidateNodeID_l(node_id node) {
-    // mLock is held.
-    mNodeIDToInstance.removeItem(node);
-}
-
 }  // namespace android
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 997cc13..72e7375 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -29,6 +29,7 @@
 
 #include <OMX_Component.h>
 #include <OMX_IndexExt.h>
+#include <OMX_VideoExt.h>
 #include <OMX_AsString.h>
 
 #include <binder/IMemory.h>
@@ -45,19 +46,19 @@
 static const OMX_U32 kPortIndexInput = 0;
 static const OMX_U32 kPortIndexOutput = 1;
 
-#define CLOGW(fmt, ...) ALOGW("[%x:%s] " fmt, mNodeID, mName, ##__VA_ARGS__)
+#define CLOGW(fmt, ...) ALOGW("[%p:%s] " fmt, mHandle, mName, ##__VA_ARGS__)
 
 #define CLOG_ERROR_IF(cond, fn, err, fmt, ...) \
-    ALOGE_IF(cond, #fn "(%x:%s, " fmt ") ERROR: %s(%#x)", \
-    mNodeID, mName, ##__VA_ARGS__, asString(err), err)
+    ALOGE_IF(cond, #fn "(%p:%s, " fmt ") ERROR: %s(%#x)", \
+    mHandle, mName, ##__VA_ARGS__, asString(err), err)
 #define CLOG_ERROR(fn, err, fmt, ...) CLOG_ERROR_IF(true, fn, err, fmt, ##__VA_ARGS__)
 #define CLOG_IF_ERROR(fn, err, fmt, ...) \
     CLOG_ERROR_IF((err) != OMX_ErrorNone, fn, err, fmt, ##__VA_ARGS__)
 
 #define CLOGI_(level, fn, fmt, ...) \
-    ALOGI_IF(DEBUG >= (level), #fn "(%x:%s, " fmt ")", mNodeID, mName, ##__VA_ARGS__)
+    ALOGI_IF(DEBUG >= (level), #fn "(%p:%s, " fmt ")", mHandle, mName, ##__VA_ARGS__)
 #define CLOGD_(level, fn, fmt, ...) \
-    ALOGD_IF(DEBUG >= (level), #fn "(%x:%s, " fmt ")", mNodeID, mName, ##__VA_ARGS__)
+    ALOGD_IF(DEBUG >= (level), #fn "(%p:%s, " fmt ")", mHandle, mName, ##__VA_ARGS__)
 
 #define CLOG_LIFE(fn, fmt, ...)     CLOGI_(ADebug::kDebugLifeCycle,     fn, fmt, ##__VA_ARGS__)
 #define CLOG_STATE(fn, fmt, ...)    CLOGI_(ADebug::kDebugState,         fn, fmt, ##__VA_ARGS__)
@@ -65,7 +66,7 @@
 #define CLOG_INTERNAL(fn, fmt, ...) CLOGD_(ADebug::kDebugInternalState, fn, fmt, ##__VA_ARGS__)
 
 #define CLOG_DEBUG_IF(cond, fn, fmt, ...) \
-    ALOGD_IF(cond, #fn "(%x, " fmt ")", mNodeID, ##__VA_ARGS__)
+    ALOGD_IF(cond, #fn "(%p, " fmt ")", mHandle, ##__VA_ARGS__)
 
 #define CLOG_BUFFER(fn, fmt, ...) \
     CLOG_DEBUG_IF(DEBUG >= ADebug::kDebugAll, fn, fmt, ##__VA_ARGS__)
@@ -206,10 +207,133 @@
     }
 }
 
+////////////////////////////////////////////////////////////////////////////////
+
+// This provides the underlying Thread used by CallbackDispatcher.
+// Note that deriving CallbackDispatcher from Thread does not work.
+
+struct OMXNodeInstance::CallbackDispatcherThread : public Thread {
+    explicit CallbackDispatcherThread(CallbackDispatcher *dispatcher)
+        : mDispatcher(dispatcher) {
+    }
+
+private:
+    CallbackDispatcher *mDispatcher;
+
+    bool threadLoop();
+
+    CallbackDispatcherThread(const CallbackDispatcherThread &);
+    CallbackDispatcherThread &operator=(const CallbackDispatcherThread &);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct OMXNodeInstance::CallbackDispatcher : public RefBase {
+    explicit CallbackDispatcher(const sp<OMXNodeInstance> &owner);
+
+    // Posts |msg| to the listener's queue. If |realTime| is true, the listener thread is notified
+    // that a new message is available on the queue. Otherwise, the message stays on the queue, but
+    // the listener is not notified of it. It will process this message when a subsequent message
+    // is posted with |realTime| set to true.
+    void post(const omx_message &msg, bool realTime = true);
+
+    bool loop();
+
+protected:
+    virtual ~CallbackDispatcher();
+
+private:
+    Mutex mLock;
+
+    sp<OMXNodeInstance> const mOwner;
+    bool mDone;
+    Condition mQueueChanged;
+    std::list<omx_message> mQueue;
+
+    sp<CallbackDispatcherThread> mThread;
+
+    void dispatch(std::list<omx_message> &messages);
+
+    CallbackDispatcher(const CallbackDispatcher &);
+    CallbackDispatcher &operator=(const CallbackDispatcher &);
+};
+
+OMXNodeInstance::CallbackDispatcher::CallbackDispatcher(const sp<OMXNodeInstance> &owner)
+    : mOwner(owner),
+      mDone(false) {
+    mThread = new CallbackDispatcherThread(this);
+    mThread->run("OMXCallbackDisp", ANDROID_PRIORITY_FOREGROUND);
+}
+
+OMXNodeInstance::CallbackDispatcher::~CallbackDispatcher() {
+    {
+        Mutex::Autolock autoLock(mLock);
+
+        mDone = true;
+        mQueueChanged.signal();
+    }
+
+    // A join on self can happen if the last ref to CallbackDispatcher
+    // is released within the CallbackDispatcherThread loop
+    status_t status = mThread->join();
+    if (status != WOULD_BLOCK) {
+        // Other than join to self, the only other error return codes are
+        // whatever readyToRun() returns, and we don't override that
+        CHECK_EQ(status, (status_t)NO_ERROR);
+    }
+}
+
+void OMXNodeInstance::CallbackDispatcher::post(const omx_message &msg, bool realTime) {
+    Mutex::Autolock autoLock(mLock);
+
+    mQueue.push_back(msg);
+    if (realTime) {
+        mQueueChanged.signal();
+    }
+}
+
+void OMXNodeInstance::CallbackDispatcher::dispatch(std::list<omx_message> &messages) {
+    if (mOwner == NULL) {
+        ALOGV("Would have dispatched a message to a node that's already gone.");
+        return;
+    }
+    mOwner->onMessages(messages);
+}
+
+bool OMXNodeInstance::CallbackDispatcher::loop() {
+    for (;;) {
+        std::list<omx_message> messages;
+
+        {
+            Mutex::Autolock autoLock(mLock);
+            while (!mDone && mQueue.empty()) {
+                mQueueChanged.wait(mLock);
+            }
+
+            if (mDone) {
+                break;
+            }
+
+            messages.swap(mQueue);
+        }
+
+        dispatch(messages);
+    }
+
+    return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool OMXNodeInstance::CallbackDispatcherThread::threadLoop() {
+    return mDispatcher->loop();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
 OMXNodeInstance::OMXNodeInstance(
         OMX *owner, const sp<IOMXObserver> &observer, const char *name)
     : mOwner(owner),
-      mNodeID(0),
       mHandle(NULL),
       mObserver(observer),
       mDying(false),
@@ -239,11 +363,13 @@
     CHECK(mHandle == NULL);
 }
 
-void OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) {
-    mNodeID = node_id;
+void OMXNodeInstance::setHandle(OMX_HANDLETYPE handle) {
     CLOG_LIFE(allocateNode, "handle=%p", handle);
     CHECK(mHandle == NULL);
     mHandle = handle;
+    if (handle != NULL) {
+        mDispatcher = new CallbackDispatcher(this);
+    }
 }
 
 sp<IOMXBufferSource> OMXNodeInstance::getBufferSource() {
@@ -257,25 +383,22 @@
     mOMXBufferSource = bufferSource;
 }
 
-OMX *OMXNodeInstance::owner() {
-    return mOwner;
+OMX_HANDLETYPE OMXNodeInstance::handle() {
+    return mHandle;
 }
 
 sp<IOMXObserver> OMXNodeInstance::observer() {
     return mObserver;
 }
 
-OMX::node_id OMXNodeInstance::nodeID() {
-    return mNodeID;
-}
+status_t OMXNodeInstance::freeNode() {
 
-status_t OMXNodeInstance::freeNode(OMXMaster *master) {
     CLOG_LIFE(freeNode, "handle=%p", mHandle);
     static int32_t kMaxNumIterations = 10;
 
     // exit if we have already freed the node
     if (mHandle == NULL) {
-        return OK;
+        return mOwner->freeNode(this);
     }
 
     // Transition the node from its current state all the way down
@@ -354,23 +477,18 @@
             LOG_ALWAYS_FATAL("unknown state %s(%#x).", asString(state), state);
             break;
     }
+    status_t err = mOwner->freeNode(this);
 
-    ALOGV("[%x:%s] calling destroyComponentInstance", mNodeID, mName);
-    OMX_ERRORTYPE err = master->destroyComponentInstance(
-            static_cast<OMX_COMPONENTTYPE *>(mHandle));
+    mDispatcher.clear();
 
     mHandle = NULL;
     CLOG_IF_ERROR(freeNode, err, "");
     free(mName);
     mName = NULL;
 
-    mOwner->invalidateNodeID(mNodeID);
-    mNodeID = 0;
-
     ALOGV("OMXNodeInstance going away.");
-    delete this;
 
-    return StatusFromOMXError(err);
+    return err;
 }
 
 status_t OMXNodeInstance::sendCommand(
@@ -1133,8 +1251,7 @@
     }
 
     sp<GraphicBufferSource> graphicBufferSource = new GraphicBufferSource(
-            mOwner,
-            mNodeID,
+            this,
             def.format.video.nFrameWidth,
             def.format.video.nFrameHeight,
             def.nBufferCountActual,
@@ -1621,6 +1738,11 @@
     return StatusFromOMXError(err);
 }
 
+status_t OMXNodeInstance::dispatchMessage(const omx_message &msg) {
+    mDispatcher->post(msg, true /*realTime*/);
+    return OMX_ErrorNone;
+}
+
 bool OMXNodeInstance::handleMessage(omx_message &msg) {
     if (msg.type == omx_message::FILL_BUFFER_DONE) {
         OMX_BUFFERHEADERTYPE *buffer =
@@ -1776,15 +1898,11 @@
     }
 }
 
-void OMXNodeInstance::onObserverDied(OMXMaster *master) {
+void OMXNodeInstance::onObserverDied() {
     ALOGE("!!! Observer died. Quickly, do something, ... anything...");
 
     // Try to force shutdown of the node and hope for the best.
-    freeNode(master);
-}
-
-void OMXNodeInstance::onGetHandleFailed() {
-    delete this;
+    freeNode();
 }
 
 // OMXNodeInstance::OnEvent calls OMX::OnEvent, which then calls here.
@@ -1861,8 +1979,39 @@
     if (instance->mDying) {
         return OMX_ErrorNone;
     }
-    return instance->owner()->OnEvent(
-            instance->nodeID(), eEvent, nData1, nData2, pEventData);
+
+    instance->onEvent(eEvent, nData1, nData2);
+
+    // output rendered events are not processed as regular events until they hit the observer
+    if (eEvent == OMX_EventOutputRendered) {
+        if (pEventData == NULL) {
+            return OMX_ErrorBadParameter;
+        }
+
+        // process data from array
+        OMX_VIDEO_RENDEREVENTTYPE *renderData = (OMX_VIDEO_RENDEREVENTTYPE *)pEventData;
+        for (size_t i = 0; i < nData1; ++i) {
+            omx_message msg;
+            msg.type = omx_message::FRAME_RENDERED;
+            msg.fenceFd = -1;
+            msg.u.render_data.timestamp = renderData[i].nMediaTimeUs;
+            msg.u.render_data.nanoTime = renderData[i].nSystemTimeNs;
+
+            instance->mDispatcher->post(msg, false /* realTime */);
+        }
+        return OMX_ErrorNone;
+    }
+
+    omx_message msg;
+    msg.type = omx_message::EVENT;
+    msg.fenceFd = -1;
+    msg.u.event_data.event = eEvent;
+    msg.u.event_data.data1 = nData1;
+    msg.u.event_data.data2 = nData2;
+
+    instance->mDispatcher->post(msg, true /* realTime */);
+
+    return OMX_ErrorNone;
 }
 
 // static
@@ -1879,8 +2028,14 @@
         return OMX_ErrorNone;
     }
     int fenceFd = instance->retrieveFenceFromMeta_l(pBuffer, kPortIndexOutput);
-    return instance->owner()->OnEmptyBufferDone(instance->nodeID(),
-            instance->findBufferID(pBuffer), pBuffer, fenceFd);
+
+    omx_message msg;
+    msg.type = omx_message::EMPTY_BUFFER_DONE;
+    msg.fenceFd = fenceFd;
+    msg.u.buffer_data.buffer = instance->findBufferID(pBuffer);
+    instance->mDispatcher->post(msg);
+
+    return OMX_ErrorNone;
 }
 
 // static
@@ -1897,8 +2052,18 @@
         return OMX_ErrorNone;
     }
     int fenceFd = instance->retrieveFenceFromMeta_l(pBuffer, kPortIndexOutput);
-    return instance->owner()->OnFillBufferDone(instance->nodeID(),
-            instance->findBufferID(pBuffer), pBuffer, fenceFd);
+
+    omx_message msg;
+    msg.type = omx_message::FILL_BUFFER_DONE;
+    msg.fenceFd = fenceFd;
+    msg.u.extended_buffer_data.buffer = instance->findBufferID(pBuffer);
+    msg.u.extended_buffer_data.range_offset = pBuffer->nOffset;
+    msg.u.extended_buffer_data.range_length = pBuffer->nFilledLen;
+    msg.u.extended_buffer_data.flags = pBuffer->nFlags;
+    msg.u.extended_buffer_data.timestamp = pBuffer->nTimeStamp;
+    instance->mDispatcher->post(msg);
+
+    return OMX_ErrorNone;
 }
 
 void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {
diff --git a/media/libstagefright/omx/OMXUtils.cpp b/media/libstagefright/omx/OMXUtils.cpp
index c5879b8..38aad39 100644
--- a/media/libstagefright/omx/OMXUtils.cpp
+++ b/media/libstagefright/omx/OMXUtils.cpp
@@ -178,7 +178,7 @@
                   : kMimeToRole[i].decoderRole;
 }
 
-status_t SetComponentRole(const sp<IOMX> &omx, IOMX::node_id node, const char *role) {
+status_t SetComponentRole(const sp<IOMXNode> &omxNode, const char *role) {
     OMX_PARAM_COMPONENTROLETYPE roleParams;
     InitOMXParams(&roleParams);
 
@@ -187,8 +187,8 @@
 
     roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
 
-    return omx->setParameter(
-            node, OMX_IndexParamStandardComponentRole,
+    return omxNode->setParameter(
+            OMX_IndexParamStandardComponentRole,
             &roleParams, sizeof(roleParams));
 }
 
@@ -305,24 +305,24 @@
 }
 
 bool DescribeColorFormat(
-        const sp<IOMX> &omx, IOMX::node_id node,
+        const sp<IOMXNode> &omxNode,
         DescribeColorFormat2Params &describeParams)
 {
     OMX_INDEXTYPE describeColorFormatIndex;
-    if (omx->getExtensionIndex(
-            node, "OMX.google.android.index.describeColorFormat",
+    if (omxNode->getExtensionIndex(
+            "OMX.google.android.index.describeColorFormat",
             &describeColorFormatIndex) == OK) {
         DescribeColorFormatParams describeParamsV1(describeParams);
-        if (omx->getParameter(
-                node, describeColorFormatIndex,
+        if (omxNode->getParameter(
+                describeColorFormatIndex,
                 &describeParamsV1, sizeof(describeParamsV1)) == OK) {
             describeParams.initFromV1(describeParamsV1);
             return describeParams.sMediaImage.mType != MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
         }
-    } else if (omx->getExtensionIndex(
-            node, "OMX.google.android.index.describeColorFormat2", &describeColorFormatIndex) == OK
-               && omx->getParameter(
-            node, describeColorFormatIndex, &describeParams, sizeof(describeParams)) == OK) {
+    } else if (omxNode->getExtensionIndex(
+            "OMX.google.android.index.describeColorFormat2", &describeColorFormatIndex) == OK
+               && omxNode->getParameter(
+                       describeColorFormatIndex, &describeParams, sizeof(describeParams)) == OK) {
         return describeParams.sMediaImage.mType != MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
     }
 
@@ -331,7 +331,7 @@
 
 // static
 bool IsFlexibleColorFormat(
-         const sp<IOMX> &omx, IOMX::node_id node,
+         const sp<IOMXNode> &omxNode,
          uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
     DescribeColorFormat2Params describeParams;
     InitOMXParams(&describeParams);
@@ -345,7 +345,7 @@
 
     CHECK(flexibleEquivalent != NULL);
 
-    if (!DescribeColorFormat(omx, node, describeParams)) {
+    if (!DescribeColorFormat(omxNode, describeParams)) {
         return false;
     }
 
diff --git a/media/libstagefright/omx/OMXUtils.h b/media/libstagefright/omx/OMXUtils.h
index 315f118..3f533ff 100644
--- a/media/libstagefright/omx/OMXUtils.h
+++ b/media/libstagefright/omx/OMXUtils.h
@@ -39,16 +39,16 @@
 status_t StatusFromOMXError(OMX_ERRORTYPE err);
 
 const char *GetComponentRole(bool isEncoder, const char *mime);
-status_t SetComponentRole(const sp<IOMX> &omx, IOMX::node_id node, const char *role);
+status_t SetComponentRole(const sp<IOMXNode> &omxNode, const char *role);
 
 struct DescribeColorFormat2Params;
 
 bool IsFlexibleColorFormat(
-        const sp<IOMX> &omx, IOMX::node_id node,
-        uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent);
+        const sp<IOMXNode> &omxNode, uint32_t colorFormat,
+        bool usingNativeBuffers, OMX_U32 *flexibleEquivalent);
 bool DescribeDefaultColorFormat(DescribeColorFormat2Params &describeParams);
 bool DescribeColorFormat(
-        const sp<IOMX> &omx, IOMX::node_id node,
+        const sp<IOMXNode> &omxNode,
         DescribeColorFormat2Params &describeParams);
 
 }  // namespace android
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index 50bb0de..277af63 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -43,6 +43,25 @@
 
 namespace android {
 
+/////////////////////////////////////////////////////////////////////
+
+struct Harness::CodecObserver : public BnOMXObserver {
+    CodecObserver(const sp<Harness> &harness, int32_t gen)
+            : mHarness(harness), mGeneration(gen) {}
+
+    void onMessages(const std::list<omx_message> &messages) override;
+
+private:
+    sp<Harness> mHarness;
+    int32_t mGeneration;
+};
+
+void Harness::CodecObserver::onMessages(const std::list<omx_message> &messages) {
+    mHarness->handleMessages(mGeneration, messages);
+}
+
+/////////////////////////////////////////////////////////////////////
+
 Harness::Harness()
     : mInitCheck(NO_INIT) {
     mInitCheck = initOMX();
@@ -64,18 +83,17 @@
     return mOMX != 0 ? OK : NO_INIT;
 }
 
-void Harness::onMessages(const std::list<omx_message> &messages) {
+void Harness::handleMessages(int32_t gen, const std::list<omx_message> &messages) {
     Mutex::Autolock autoLock(mLock);
     for (std::list<omx_message>::const_iterator it = messages.cbegin(); it != messages.cend(); ) {
         mMessageQueue.push_back(*it++);
+        mLastMsgGeneration = gen;
     }
     mMessageAddedCondition.signal();
 }
 
-status_t Harness::dequeueMessageForNode(
-        IOMX::node_id node, omx_message *msg, int64_t timeoutUs) {
-    return dequeueMessageForNodeIgnoringBuffers(
-            node, NULL, NULL, msg, timeoutUs);
+status_t Harness::dequeueMessageForNode(omx_message *msg, int64_t timeoutUs) {
+    return dequeueMessageForNodeIgnoringBuffers(NULL, NULL, msg, timeoutUs);
 }
 
 // static
@@ -120,7 +138,6 @@
 }
 
 status_t Harness::dequeueMessageForNodeIgnoringBuffers(
-        IOMX::node_id node,
         Vector<Buffer> *inputBuffers,
         Vector<Buffer> *outputBuffers,
         omx_message *msg, int64_t timeoutUs) {
@@ -128,21 +145,22 @@
 
     for (;;) {
         Mutex::Autolock autoLock(mLock);
+        // Messages are queued in batches, if the last batch queued is
+        // from a node that already expired, discard those messages.
+        if (mLastMsgGeneration < mCurGeneration) {
+            mMessageQueue.clear();
+        }
         List<omx_message>::iterator it = mMessageQueue.begin();
         while (it != mMessageQueue.end()) {
-            if ((*it).node == node) {
-                if (handleBufferMessage(*it, inputBuffers, outputBuffers)) {
-                    it = mMessageQueue.erase(it);
-                    continue;
-                }
-
-                *msg = *it;
-                mMessageQueue.erase(it);
-
-                return OK;
+            if (handleBufferMessage(*it, inputBuffers, outputBuffers)) {
+                it = mMessageQueue.erase(it);
+                continue;
             }
 
-            ++it;
+            *msg = *it;
+            mMessageQueue.erase(it);
+
+            return OK;
         }
 
         status_t err = (timeoutUs < 0)
@@ -158,16 +176,15 @@
 }
 
 status_t Harness::getPortDefinition(
-        IOMX::node_id node, OMX_U32 portIndex,
-        OMX_PARAM_PORTDEFINITIONTYPE *def) {
+        OMX_U32 portIndex, OMX_PARAM_PORTDEFINITIONTYPE *def) {
     def->nSize = sizeof(*def);
     def->nVersion.s.nVersionMajor = 1;
     def->nVersion.s.nVersionMinor = 0;
     def->nVersion.s.nRevision = 0;
     def->nVersion.s.nStep = 0;
     def->nPortIndex = portIndex;
-    return mOMX->getParameter(
-            node, OMX_IndexParamPortDefinition, def, sizeof(*def));
+    return mOMXNode->getParameter(
+            OMX_IndexParamPortDefinition, def, sizeof(*def));
 }
 
 #define EXPECT(condition, info) \
@@ -180,12 +197,11 @@
 
 status_t Harness::allocatePortBuffers(
         const sp<MemoryDealer> &dealer,
-        IOMX::node_id node, OMX_U32 portIndex,
-        Vector<Buffer> *buffers) {
+        OMX_U32 portIndex, Vector<Buffer> *buffers) {
     buffers->clear();
 
     OMX_PARAM_PORTDEFINITIONTYPE def;
-    status_t err = getPortDefinition(node, portIndex, &def);
+    status_t err = getPortDefinition(portIndex, &def);
     EXPECT_SUCCESS(err, "getPortDefinition");
 
     for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
@@ -194,8 +210,8 @@
         buffer.mFlags = 0;
         CHECK(buffer.mMemory != NULL);
 
-        err = mOMX->allocateBufferWithBackup(
-                node, portIndex, buffer.mMemory, &buffer.mID, buffer.mMemory->size());
+        err = mOMXNode->allocateBufferWithBackup(
+                portIndex, buffer.mMemory, &buffer.mID, buffer.mMemory->size());
         EXPECT_SUCCESS(err, "allocateBuffer");
 
         buffers->push(buffer);
@@ -204,7 +220,7 @@
     return OK;
 }
 
-status_t Harness::setRole(IOMX::node_id node, const char *role) {
+status_t Harness::setRole(const char *role) {
     OMX_PARAM_COMPONENTROLETYPE params;
     params.nSize = sizeof(params);
     params.nVersion.s.nVersionMajor = 1;
@@ -214,31 +230,31 @@
     strncpy((char *)params.cRole, role, OMX_MAX_STRINGNAME_SIZE - 1);
     params.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
 
-    return mOMX->setParameter(
-            node, OMX_IndexParamStandardComponentRole,
+    return mOMXNode->setParameter(
+            OMX_IndexParamStandardComponentRole,
             &params, sizeof(params));
 }
 
 struct NodeReaper {
-    NodeReaper(const sp<Harness> &harness, IOMX::node_id node)
+    NodeReaper(const sp<Harness> &harness, const sp<IOMXNode> &omxNode)
         : mHarness(harness),
-          mNode(node) {
+          mOMXNode(omxNode) {
     }
 
     ~NodeReaper() {
-        if (mNode != 0) {
-            mHarness->mOMX->freeNode(mNode);
-            mNode = 0;
+        if (mOMXNode != 0) {
+            mOMXNode->freeNode();
+            mOMXNode = NULL;
         }
     }
 
     void disarm() {
-        mNode = 0;
+        mOMXNode = NULL;
     }
 
 private:
     sp<Harness> mHarness;
-    IOMX::node_id mNode;
+    sp<IOMXNode> mOMXNode;
 
     NodeReaper(const NodeReaper &);
     NodeReaper &operator=(const NodeReaper &);
@@ -264,23 +280,24 @@
     }
 
     sp<MemoryDealer> dealer = new MemoryDealer(16 * 1024 * 1024, "OMXHarness");
-    IOMX::node_id node;
+
+    sp<CodecObserver> observer = new CodecObserver(this, ++mCurGeneration);
 
     status_t err =
-        mOMX->allocateNode(componentName, this, NULL, &node);
+        mOMX->allocateNode(componentName, observer, NULL, &mOMXNode);
     EXPECT_SUCCESS(err, "allocateNode");
 
-    NodeReaper reaper(this, node);
+    NodeReaper reaper(this, mOMXNode);
 
-    err = setRole(node, componentRole);
+    err = setRole(componentRole);
     EXPECT_SUCCESS(err, "setRole");
 
     // Initiate transition Loaded->Idle
-    err = mOMX->sendCommand(node, OMX_CommandStateSet, OMX_StateIdle);
+    err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
     EXPECT_SUCCESS(err, "sendCommand(go-to-Idle)");
 
     omx_message msg;
-    err = dequeueMessageForNode(node, &msg, DEFAULT_TIMEOUT);
+    err = dequeueMessageForNode(&msg, DEFAULT_TIMEOUT);
     // Make sure node doesn't just transition to idle before we are done
     // allocating all input and output buffers.
     EXPECT(err == TIMED_OUT,
@@ -289,17 +306,17 @@
 
     // Now allocate buffers.
     Vector<Buffer> inputBuffers;
-    err = allocatePortBuffers(dealer, node, 0, &inputBuffers);
+    err = allocatePortBuffers(dealer, 0, &inputBuffers);
     EXPECT_SUCCESS(err, "allocatePortBuffers(input)");
 
-    err = dequeueMessageForNode(node, &msg, DEFAULT_TIMEOUT);
+    err = dequeueMessageForNode(&msg, DEFAULT_TIMEOUT);
     CHECK_EQ(err, (status_t)TIMED_OUT);
 
     Vector<Buffer> outputBuffers;
-    err = allocatePortBuffers(dealer, node, 1, &outputBuffers);
+    err = allocatePortBuffers(dealer, 1, &outputBuffers);
     EXPECT_SUCCESS(err, "allocatePortBuffers(output)");
 
-    err = dequeueMessageForNode(node, &msg, DEFAULT_TIMEOUT);
+    err = dequeueMessageForNode(&msg, DEFAULT_TIMEOUT);
     EXPECT(err == OK
             && msg.type == omx_message::EVENT
             && msg.u.event_data.event == OMX_EventCmdComplete
@@ -309,10 +326,10 @@
            "after all input and output buffers were allocated.");
 
     // Initiate transition Idle->Executing
-    err = mOMX->sendCommand(node, OMX_CommandStateSet, OMX_StateExecuting);
+    err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateExecuting);
     EXPECT_SUCCESS(err, "sendCommand(go-to-Executing)");
 
-    err = dequeueMessageForNode(node, &msg, DEFAULT_TIMEOUT);
+    err = dequeueMessageForNode(&msg, DEFAULT_TIMEOUT);
     EXPECT(err == OK
             && msg.type == omx_message::EVENT
             && msg.u.event_data.event == OMX_EventCmdComplete
@@ -322,17 +339,17 @@
            "executing state.");
 
     for (size_t i = 0; i < outputBuffers.size(); ++i) {
-        err = mOMX->fillBuffer(node, outputBuffers[i].mID);
+        err = mOMXNode->fillBuffer(outputBuffers[i].mID);
         EXPECT_SUCCESS(err, "fillBuffer");
 
         outputBuffers.editItemAt(i).mFlags |= kBufferBusy;
     }
 
-    err = mOMX->sendCommand(node, OMX_CommandFlush, 1);
+    err = mOMXNode->sendCommand(OMX_CommandFlush, 1);
     EXPECT_SUCCESS(err, "sendCommand(flush-output-port)");
 
     err = dequeueMessageForNodeIgnoringBuffers(
-            node, &inputBuffers, &outputBuffers, &msg, DEFAULT_TIMEOUT);
+            &inputBuffers, &outputBuffers, &msg, DEFAULT_TIMEOUT);
     EXPECT(err == OK
             && msg.type == omx_message::EVENT
             && msg.u.event_data.event == OMX_EventCmdComplete
@@ -347,18 +364,18 @@
     }
 
     for (size_t i = 0; i < outputBuffers.size(); ++i) {
-        err = mOMX->fillBuffer(node, outputBuffers[i].mID);
+        err = mOMXNode->fillBuffer(outputBuffers[i].mID);
         EXPECT_SUCCESS(err, "fillBuffer");
 
         outputBuffers.editItemAt(i).mFlags |= kBufferBusy;
     }
 
     // Initiate transition Executing->Idle
-    err = mOMX->sendCommand(node, OMX_CommandStateSet, OMX_StateIdle);
+    err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
     EXPECT_SUCCESS(err, "sendCommand(go-to-Idle)");
 
     err = dequeueMessageForNodeIgnoringBuffers(
-            node, &inputBuffers, &outputBuffers, &msg, DEFAULT_TIMEOUT);
+            &inputBuffers, &outputBuffers, &msg, DEFAULT_TIMEOUT);
     EXPECT(err == OK
             && msg.type == omx_message::EVENT
             && msg.u.event_data.event == OMX_EventCmdComplete
@@ -382,28 +399,28 @@
     }
 
     // Initiate transition Idle->Loaded
-    err = mOMX->sendCommand(node, OMX_CommandStateSet, OMX_StateLoaded);
+    err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateLoaded);
     EXPECT_SUCCESS(err, "sendCommand(go-to-Loaded)");
 
     // Make sure node doesn't just transition to loaded before we are done
     // freeing all input and output buffers.
-    err = dequeueMessageForNode(node, &msg, DEFAULT_TIMEOUT);
+    err = dequeueMessageForNode(&msg, DEFAULT_TIMEOUT);
     CHECK_EQ(err, (status_t)TIMED_OUT);
 
     for (size_t i = 0; i < inputBuffers.size(); ++i) {
-        err = mOMX->freeBuffer(node, 0, inputBuffers[i].mID);
+        err = mOMXNode->freeBuffer(0, inputBuffers[i].mID);
         EXPECT_SUCCESS(err, "freeBuffer");
     }
 
-    err = dequeueMessageForNode(node, &msg, DEFAULT_TIMEOUT);
+    err = dequeueMessageForNode(&msg, DEFAULT_TIMEOUT);
     CHECK_EQ(err, (status_t)TIMED_OUT);
 
     for (size_t i = 0; i < outputBuffers.size(); ++i) {
-        err = mOMX->freeBuffer(node, 1, outputBuffers[i].mID);
+        err = mOMXNode->freeBuffer(1, outputBuffers[i].mID);
         EXPECT_SUCCESS(err, "freeBuffer");
     }
 
-    err = dequeueMessageForNode(node, &msg, DEFAULT_TIMEOUT);
+    err = dequeueMessageForNode(&msg, DEFAULT_TIMEOUT);
     EXPECT(err == OK
             && msg.type == omx_message::EVENT
             && msg.u.event_data.event == OMX_EventCmdComplete
@@ -412,12 +429,12 @@
            "Component did not properly transition to from idle to "
            "loaded state after freeing all input and output buffers.");
 
-    err = mOMX->freeNode(node);
+    err = mOMXNode->freeNode();
     EXPECT_SUCCESS(err, "freeNode");
 
     reaper.disarm();
 
-    node = 0;
+    mOMXNode = NULL;
 
     return OK;
 }
diff --git a/media/libstagefright/omx/tests/OMXHarness.h b/media/libstagefright/omx/tests/OMXHarness.h
index 1ebf3aa..0fe00a6 100644
--- a/media/libstagefright/omx/tests/OMXHarness.h
+++ b/media/libstagefright/omx/tests/OMXHarness.h
@@ -29,7 +29,7 @@
 
 class MemoryDealer;
 
-struct Harness : public BnOMXObserver {
+struct Harness : public RefBase {
     enum BufferFlags {
         kBufferBusy = 1
     };
@@ -43,25 +43,21 @@
 
     status_t initCheck() const;
 
-    status_t dequeueMessageForNode(
-            IOMX::node_id node, omx_message *msg, int64_t timeoutUs = -1);
+    status_t dequeueMessageForNode(omx_message *msg, int64_t timeoutUs = -1);
 
     status_t dequeueMessageForNodeIgnoringBuffers(
-            IOMX::node_id node,
             Vector<Buffer> *inputBuffers,
             Vector<Buffer> *outputBuffers,
             omx_message *msg, int64_t timeoutUs = -1);
 
     status_t getPortDefinition(
-            IOMX::node_id node, OMX_U32 portIndex,
-            OMX_PARAM_PORTDEFINITIONTYPE *def);
+            OMX_U32 portIndex, OMX_PARAM_PORTDEFINITIONTYPE *def);
 
     status_t allocatePortBuffers(
             const sp<MemoryDealer> &dealer,
-            IOMX::node_id node, OMX_U32 portIndex,
-            Vector<Buffer> *buffers);
+            OMX_U32 portIndex, Vector<Buffer> *buffers);
 
-    status_t setRole(IOMX::node_id node, const char *role);
+    status_t setRole(const char *role);
 
     status_t testStateTransitions(
             const char *componentName, const char *componentRole);
@@ -74,20 +70,22 @@
 
     status_t testAll();
 
-    virtual void onMessages(const std::list<omx_message> &messages);
-
 protected:
     virtual ~Harness();
 
 private:
     friend struct NodeReaper;
+    struct CodecObserver;
 
     Mutex mLock;
 
     status_t mInitCheck;
     sp<IOMX> mOMX;
+    sp<IOMXNode> mOMXNode;
     List<omx_message> mMessageQueue;
     Condition mMessageAddedCondition;
+    int32_t mLastMsgGeneration;
+    int32_t mCurGeneration;
 
     status_t initOMX();
 
@@ -96,6 +94,8 @@
             Vector<Buffer> *inputBuffers,
             Vector<Buffer> *outputBuffers);
 
+    void handleMessages(int32_t gen, const std::list<omx_message> &messages);
+
     Harness(const Harness &);
     Harness &operator=(const Harness &);
 };