diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 376f3d9..ad6540a 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -345,12 +345,12 @@
         sp<IOMX> omx = service->getOMX();
         CHECK(omx.get() != NULL);
 
-        List<String8> list;
+        List<IOMX::ComponentInfo> list;
         omx->listNodes(&list);
 
-        for (List<String8>::iterator it = list.begin();
+        for (List<IOMX::ComponentInfo>::iterator it = list.begin();
              it != list.end(); ++it) {
-            printf("%s\n", (*it).string());
+            printf("%s\n", (*it).mName.string());
         }
     }
 
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 6f3ba1c..39bd5b1 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -42,7 +42,11 @@
     typedef void *buffer_id;
     typedef void *node_id;
 
-    virtual status_t listNodes(List<String8> *list) = 0;
+    struct ComponentInfo {
+        String8 mName;
+        List<String8> mRoles;
+    };
+    virtual status_t listNodes(List<ComponentInfo> *list) = 0;
 
     virtual status_t allocateNode(
             const char *name, const sp<IOMXObserver> &observer,
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 76a9e7d..b43e48f 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -75,7 +75,7 @@
         : BpInterface<IOMX>(impl) {
     }
 
-    virtual status_t listNodes(List<String8> *list) {
+    virtual status_t listNodes(List<ComponentInfo> *list) {
         list->clear();
 
         Parcel data, reply;
@@ -84,9 +84,14 @@
 
         int32_t n = reply.readInt32();
         for (int32_t i = 0; i < n; ++i) {
-            String8 s = reply.readString8();
+            list->push_back(ComponentInfo());
+            ComponentInfo &info = *--list->end();
 
-            list->push_back(s);
+            info.mName = reply.readString8();
+            int32_t numRoles = reply.readInt32();
+            for (int32_t j = 0; j < numRoles; ++j) {
+                info.mRoles.push_back(reply.readString8());
+            }
         }
 
         return OK;
@@ -368,13 +373,20 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            List<String8> list;
+            List<ComponentInfo> list;
             listNodes(&list);
 
             reply->writeInt32(list.size());
-            for (List<String8>::iterator it = list.begin();
+            for (List<ComponentInfo>::iterator it = list.begin();
                  it != list.end(); ++it) {
-                reply->writeString8(*it);
+                ComponentInfo &cur = *it;
+
+                reply->writeString8(cur.mName);
+                reply->writeInt32(cur.mRoles.size());
+                for (List<String8>::iterator role_it = cur.mRoles.begin();
+                     role_it != cur.mRoles.end(); ++role_it) {
+                    reply->writeString8(*role_it);
+                }
             }
 
             return NO_ERROR;
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 7969710..143e8ee 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -534,8 +534,8 @@
             uint16_t sample_size = U16_AT(&buffer[18]);
             uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
 
-            printf("*** coding='%s' %d channels, size %d, rate %d\n",
-                   chunk, num_channels, sample_size, sample_rate);
+            // printf("*** coding='%s' %d channels, size %d, rate %d\n",
+            //        chunk, num_channels, sample_size, sample_rate);
 
             mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
             mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
@@ -576,8 +576,8 @@
             uint16_t width = U16_AT(&buffer[6 + 18]);
             uint16_t height = U16_AT(&buffer[6 + 20]);
 
-            printf("*** coding='%s' width=%d height=%d\n",
-                   chunk, width, height);
+            // printf("*** coding='%s' width=%d height=%d\n",
+            //        chunk, width, height);
 
             mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
             mLastTrack->meta->setInt32(kKeyWidth, width);
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 99c39f8..47bbda3 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -425,14 +425,9 @@
         esds.getCodecSpecificInfo(
                 &codec_specific_data, &codec_specific_data_size);
 
-        printf("found codec-specific data of size %d\n",
-               codec_specific_data_size);
-
         codec->addCodecSpecificData(
                 codec_specific_data, codec_specific_data_size);
     } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
-        printf("found avcc of size %d\n", size);
-
         // Parse the AVCDecoderConfigurationRecord
 
         const uint8_t *ptr = (const uint8_t *)data;
@@ -1223,7 +1218,7 @@
              portIndex == kPortIndexInput ? "input" : "output");
     }
 
-    dumpPortStatus(portIndex);
+    // dumpPortStatus(portIndex);
 
     return OK;
 }
@@ -1273,7 +1268,6 @@
                 CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED);
                 drainInputBuffer(&buffers->editItemAt(i));
             }
-
             break;
         }
 
@@ -1282,12 +1276,10 @@
             IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
             OMX_U32 flags = msg.u.extended_buffer_data.flags;
 
-            CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx)",
+            CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))",
                  buffer,
                  msg.u.extended_buffer_data.range_length,
-                 flags);
-
-            CODEC_LOGV("FILL_BUFFER_DONE(timestamp: %lld us (%.2f secs))",
+                 flags,
                  msg.u.extended_buffer_data.timestamp,
                  msg.u.extended_buffer_data.timestamp / 1E6);
 
@@ -1315,11 +1307,13 @@
                 CHECK_EQ(err, OK);
 
                 buffers->removeAt(i);
+#if 0
             } else if (mPortStatus[kPortIndexOutput] == ENABLED
                        && (flags & OMX_BUFFERFLAG_EOS)) {
                 CODEC_LOGV("No more output data.");
                 mNoMoreOutputData = true;
                 mBufferFilled.signal();
+#endif
             } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
                 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
 
@@ -1351,6 +1345,11 @@
 
                 mFilledBuffers.push_back(i);
                 mBufferFilled.signal();
+
+                if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
+                    CODEC_LOGV("No more output data.");
+                    mNoMoreOutputData = true;
+                }
             }
 
             break;
@@ -1374,7 +1373,7 @@
 
         case OMX_EventError:
         {
-            LOGE("ERROR(%ld, %ld)", data1, data2);
+            LOGE("ERROR(0x%08lx, %ld)", data1, data2);
 
             setState(ERROR);
             break;
@@ -1386,6 +1385,7 @@
             break;
         }
 
+#if 0
         case OMX_EventBufferFlag:
         {
             CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
@@ -1395,6 +1395,7 @@
             }
             break;
         }
+#endif
 
         default:
         {
@@ -1565,13 +1566,6 @@
                     CODEC_LOGV("Finished flushing both ports, now continuing from"
                          " seek-time.");
 
-                    // Clear this flag in case the decoder sent us either
-                    // the EVENT_BUFFER_FLAG(1) or an output buffer with
-                    // the EOS flag set _while_ flushing. Since we're going
-                    // to submit "fresh" input data now, this flag no longer
-                    // applies to our future.
-                    mNoMoreOutputData = false;
-
                     drainInputBuffers();
                     fillOutputBuffers();
                 }
@@ -1832,6 +1826,8 @@
             memcpy(info->mMem->pointer(), specific->mData, specific->mSize);
         }
 
+        mNoMoreOutputData = false;
+
         status_t err = mOMX->emptyBuffer(
                 mNode, info->mBuffer, 0, size,
                 OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_CODECCONFIG,
@@ -1849,7 +1845,9 @@
     if (mSeekTimeUs >= 0) {
         MediaSource::ReadOptions options;
         options.setSeekTo(mSeekTimeUs);
+
         mSeekTimeUs = -1;
+        mBufferFilled.signal();
 
         err = mSource->read(&srcBuffer, &options);
     } else {
@@ -1866,6 +1864,8 @@
 
         mSignalledEOS = true;
     } else {
+        mNoMoreOutputData = false;
+
         srcLength = srcBuffer->range_length();
 
         if (info->mMem->size() < srcLength) {
@@ -1878,10 +1878,10 @@
                srcLength);
 
         if (srcBuffer->meta_data()->findInt64(kKeyTime, &timestampUs)) {
-            CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d)",
-                 info->mBuffer, srcLength);
-            CODEC_LOGV("Calling emptyBuffer with timestamp %lld us (%.2f secs)",
-                 timestampUs, timestampUs / 1E6);
+            CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
+                       "timestamp %lld us (%.2f secs)",
+                       info->mBuffer, srcLength,
+                       timestampUs, timestampUs / 1E6);
         }
     }
 
@@ -2298,7 +2298,6 @@
         CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
 
         mSignalledEOS = false;
-        mNoMoreOutputData = false;
 
         CHECK(seekTimeUs >= 0);
         mSeekTimeUs = seekTimeUs;
@@ -2317,6 +2316,10 @@
         if (emulateOutputFlushCompletion) {
             onCmdComplete(OMX_CommandFlush, kPortIndexOutput);
         }
+
+        while (mSeekTimeUs >= 0) {
+            mBufferFilled.wait(mLock);
+        }
     }
 
     while (mState != ERROR && !mNoMoreOutputData && mFilledBuffers.empty()) {
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index 01b8e7a..ce0b0d55aa 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -31,7 +31,7 @@
 public:
     OMX();
 
-    virtual status_t listNodes(List<String8> *list);
+    virtual status_t listNodes(List<ComponentInfo> *list);
 
     virtual status_t allocateNode(
             const char *name, const sp<IOMXObserver> &observer, node_id *node);
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index 19d3940..923b801 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -85,6 +85,7 @@
     OMX::node_id mNodeID;
     OMX_HANDLETYPE mHandle;
     sp<IOMXObserver> mObserver;
+    bool mDying;
 
     struct ActiveBuffer {
         OMX_U32 mPortIndex;
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index 4f88d99..2473731 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -47,3 +47,6 @@
 LOCAL_MODULE:= libstagefright_omx
 
 include $(BUILD_SHARED_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 94dbb6d..8c3f252 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -208,39 +208,27 @@
     instance->onObserverDied(mMaster);
 }
 
-#if 0
-static void dumpRoles(OMXMaster *master, const char *name) {
-    Vector<String8> roles;
-    OMX_ERRORTYPE err = master->getRolesOfComponent(name, &roles);
-
-    if (err != OMX_ErrorNone) {
-        LOGE("Could not get roles for component '%s'.", name);
-        return;
-    }
-
-    if (roles.isEmpty()) {
-        LOGE("Component '%s' has NO roles!", name);
-        return;
-    }
-
-    LOGI("Component '%s' has the following roles:", name);
-
-    for (size_t i = 0; i < roles.size(); ++i) {
-        LOGI("%d) %s", i + 1, roles[i].string());
-    }
-}
-#endif
-
-status_t OMX::listNodes(List<String8> *list) {
+status_t OMX::listNodes(List<ComponentInfo> *list) {
     list->clear();
 
     OMX_U32 index = 0;
     char componentName[256];
     while (mMaster->enumerateComponents(
                 componentName, sizeof(componentName), index) == OMX_ErrorNone) {
-        list->push_back(String8(componentName));
+        list->push_back(ComponentInfo());
+        ComponentInfo &info = *--list->end();
 
-        // dumpRoles(mMaster, componentName);
+        info.mName = componentName;
+
+        Vector<String8> roles;
+        OMX_ERRORTYPE err =
+            mMaster->getRolesOfComponent(componentName, &roles);
+
+        if (err == OMX_ErrorNone) {
+            for (OMX_U32 i = 0; i < roles.size(); ++i) {
+                info.mRoles.push_back(roles[i]);
+            }
+        }
 
         ++index;
     }
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 288710e..4eb6417 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -78,7 +78,8 @@
     : mOwner(owner),
       mNodeID(NULL),
       mHandle(NULL),
-      mObserver(observer) {
+      mObserver(observer),
+      mDying(false) {
 }
 
 OMXNodeInstance::~OMXNodeInstance() {
@@ -114,6 +115,11 @@
     // for components that don't do this themselves on a call to
     // "FreeHandle".
 
+    // The code below may trigger some more events to be dispatched
+    // by the OMX component - we want to ignore them as our client
+    // does not expect them.
+    mDying = true;
+
     OMX_STATETYPE state;
     CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone);
     switch (state) {
@@ -406,6 +412,9 @@
         OMX_IN OMX_U32 nData2,
         OMX_IN OMX_PTR pEventData) {
     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
+    if (instance->mDying) {
+        return OMX_ErrorNone;
+    }
     return instance->owner()->OnEvent(
             instance->nodeID(), eEvent, nData1, nData2, pEventData);
 }
@@ -416,6 +425,9 @@
         OMX_IN OMX_PTR pAppData,
         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
+    if (instance->mDying) {
+        return OMX_ErrorNone;
+    }
     return instance->owner()->OnEmptyBufferDone(instance->nodeID(), pBuffer);
 }
 
@@ -425,6 +437,9 @@
         OMX_IN OMX_PTR pAppData,
         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
     OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
+    if (instance->mDying) {
+        return OMX_ErrorNone;
+    }
     return instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer);
 }
 
diff --git a/media/libstagefright/omx/tests/Android.mk b/media/libstagefright/omx/tests/Android.mk
new file mode 100644
index 0000000..cd654510
--- /dev/null
+++ b/media/libstagefright/omx/tests/Android.mk
@@ -0,0 +1,23 @@
+ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES =       \
+	OMXHarness.cpp  \
+
+LOCAL_SHARED_LIBRARIES := \
+	libstagefright
+
+LOCAL_C_INCLUDES:= \
+	$(JNI_H_INCLUDE) \
+	frameworks/base/media/libstagefright \
+	$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include
+
+LOCAL_MODULE:= omx_tests
+
+include $(BUILD_EXECUTABLE)
+
+endif
+
+
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
new file mode 100644
index 0000000..2e23899
--- /dev/null
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -0,0 +1,815 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "OMXHarness"
+#include <utils/Log.h>
+
+#include "OMXHarness.h"
+
+#include <sys/time.h>
+
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+#include <binder/MemoryDealer.h>
+#include <media/IMediaPlayerService.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/OMXCodec.h>
+
+#define DEFAULT_TIMEOUT         500000
+
+namespace android {
+
+static int64_t getNowUs() {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+
+    return (int64_t)tv.tv_usec + tv.tv_sec * 1000000;
+}
+
+Harness::Harness()
+    : mInitCheck(NO_INIT) {
+    mInitCheck = initOMX();
+}
+
+Harness::~Harness() {
+}
+
+status_t Harness::initCheck() const {
+    return mInitCheck;
+}
+
+status_t Harness::initOMX() {
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("media.player"));
+    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
+    mOMX = service->getOMX();
+
+    return mOMX != 0 ? OK : NO_INIT;
+}
+
+void Harness::onMessage(const omx_message &msg) {
+    Mutex::Autolock autoLock(mLock);
+    mMessageQueue.push_back(msg);
+    mMessageAddedCondition.signal();
+}
+
+status_t Harness::dequeueMessageForNode(
+        IOMX::node_id node, omx_message *msg, int64_t timeoutUs) {
+    return dequeueMessageForNodeIgnoringBuffers(
+            node, NULL, NULL, msg, timeoutUs);
+}
+
+// static
+bool Harness::handleBufferMessage(
+        const omx_message &msg,
+        Vector<Buffer> *inputBuffers,
+        Vector<Buffer> *outputBuffers) {
+    switch (msg.type) {
+        case omx_message::EMPTY_BUFFER_DONE:
+        {
+            if (inputBuffers) {
+                for (size_t i = 0; i < inputBuffers->size(); ++i) {
+                    if ((*inputBuffers)[i].mID == msg.u.buffer_data.buffer) {
+                        inputBuffers->editItemAt(i).mFlags &= ~kBufferBusy;
+                        return true;
+                    }
+                }
+                CHECK(!"should not be here");
+            }
+            break;
+        }
+
+        case omx_message::FILL_BUFFER_DONE:
+        {
+            if (outputBuffers) {
+                for (size_t i = 0; i < outputBuffers->size(); ++i) {
+                    if ((*outputBuffers)[i].mID == msg.u.buffer_data.buffer) {
+                        outputBuffers->editItemAt(i).mFlags &= ~kBufferBusy;
+                        return true;
+                    }
+                }
+                CHECK(!"should not be here");
+            }
+            break;
+        }
+
+        default:
+            break;
+    }
+
+    return false;
+}
+
+status_t Harness::dequeueMessageForNodeIgnoringBuffers(
+        IOMX::node_id node,
+        Vector<Buffer> *inputBuffers,
+        Vector<Buffer> *outputBuffers,
+        omx_message *msg, int64_t timeoutUs) {
+    int64_t finishBy = getNowUs() + timeoutUs;
+
+    for (;;) {
+        Mutex::Autolock autoLock(mLock);
+        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;
+            }
+
+            ++it;
+        }
+
+        status_t err = (timeoutUs < 0)
+            ? mMessageAddedCondition.wait(mLock)
+            : mMessageAddedCondition.waitRelative(
+                    mLock, (finishBy - getNowUs()) * 1000);
+
+        if (err == TIMED_OUT) {
+            return err;
+        }
+        CHECK_EQ(err, OK);
+    }
+}
+
+status_t Harness::getPortDefinition(
+        IOMX::node_id node, 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));
+}
+
+#define EXPECT(condition, info) \
+    if (!(condition)) {         \
+        LOGE(info); printf("\n  * " info "\n"); return UNKNOWN_ERROR; \
+    }
+
+#define EXPECT_SUCCESS(err, info) \
+    EXPECT((err) == OK, info " failed")
+
+status_t Harness::allocatePortBuffers(
+        const sp<MemoryDealer> &dealer,
+        IOMX::node_id node, OMX_U32 portIndex,
+        Vector<Buffer> *buffers) {
+    buffers->clear();
+
+    OMX_PARAM_PORTDEFINITIONTYPE def;
+    status_t err = getPortDefinition(node, portIndex, &def);
+    EXPECT_SUCCESS(err, "getPortDefinition");
+
+    for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
+        Buffer buffer;
+        buffer.mMemory = dealer->allocate(def.nBufferSize);
+        buffer.mFlags = 0;
+        CHECK(buffer.mMemory != NULL);
+
+        err = mOMX->allocateBufferWithBackup(
+                node, portIndex, buffer.mMemory, &buffer.mID);
+        EXPECT_SUCCESS(err, "allocateBuffer");
+
+        buffers->push(buffer);
+    }
+
+    return OK;
+}
+
+status_t Harness::setRole(IOMX::node_id node, const char *role) {
+    OMX_PARAM_COMPONENTROLETYPE params;
+    params.nSize = sizeof(params);
+    params.nVersion.s.nVersionMajor = 1;
+    params.nVersion.s.nVersionMinor = 0;
+    params.nVersion.s.nRevision = 0;
+    params.nVersion.s.nStep = 0;
+    strncpy((char *)params.cRole, role, OMX_MAX_STRINGNAME_SIZE - 1);
+    params.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
+
+    return mOMX->setParameter(
+            node, OMX_IndexParamStandardComponentRole,
+            &params, sizeof(params));
+}
+
+struct NodeReaper {
+    NodeReaper(const sp<Harness> &harness, IOMX::node_id node)
+        : mHarness(harness),
+          mNode(node) {
+    }
+
+    ~NodeReaper() {
+        if (mNode != 0) {
+            mHarness->mOMX->freeNode(mNode);
+            mNode = 0;
+        }
+    }
+
+    void disarm() {
+        mNode = 0;
+    }
+
+private:
+    sp<Harness> mHarness;
+    IOMX::node_id mNode;
+
+    NodeReaper(const NodeReaper &);
+    NodeReaper &operator=(const NodeReaper &);
+};
+
+static sp<MediaSource> MakeSource(
+        const char *uri,
+        const char *mimeType) {
+    sp<MediaExtractor> extractor = MediaExtractor::CreateFromURI(uri);
+
+    if (extractor == NULL) {
+        return NULL;
+    }
+
+    for (size_t i = 0; i < extractor->countTracks(); ++i) {
+        sp<MetaData> meta = extractor->getTrackMetaData(i);
+
+        const char *trackMIME;
+        CHECK(meta->findCString(kKeyMIMEType, &trackMIME));
+
+        if (!strcasecmp(trackMIME, mimeType)) {
+            return extractor->getTrack(i);
+        }
+    }
+
+    return NULL;
+}
+
+status_t Harness::testStateTransitions(
+        const char *componentName, const char *componentRole) {
+    if (strncmp(componentName, "OMX.", 4)) {
+        // Non-OMX components, i.e. software decoders won't execute this
+        // test.
+        return OK;
+    }
+
+    sp<MemoryDealer> dealer = new MemoryDealer(8 * 1024 * 1024);
+    IOMX::node_id node;
+
+    status_t err =
+        mOMX->allocateNode(componentName, this, &node);
+    EXPECT_SUCCESS(err, "allocateNode");
+
+    NodeReaper reaper(this, node);
+
+    err = setRole(node, componentRole);
+    EXPECT_SUCCESS(err, "setRole");
+
+    // Initiate transition Loaded->Idle
+    err = mOMX->sendCommand(node, OMX_CommandStateSet, OMX_StateIdle);
+    EXPECT_SUCCESS(err, "sendCommand(go-to-Idle)");
+
+    omx_message msg;
+    err = dequeueMessageForNode(node, &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,
+            "Component must not transition from loaded to idle before "
+            "all input and output buffers are allocated.");
+
+    // Now allocate buffers.
+    Vector<Buffer> inputBuffers;
+    err = allocatePortBuffers(dealer, node, 0, &inputBuffers);
+    EXPECT_SUCCESS(err, "allocatePortBuffers(input)");
+
+    err = dequeueMessageForNode(node, &msg, DEFAULT_TIMEOUT);
+    CHECK_EQ(err, TIMED_OUT);
+
+    Vector<Buffer> outputBuffers;
+    err = allocatePortBuffers(dealer, node, 1, &outputBuffers);
+    EXPECT_SUCCESS(err, "allocatePortBuffers(output)");
+
+    err = dequeueMessageForNode(node, &msg, DEFAULT_TIMEOUT);
+    EXPECT(err == OK
+            && msg.type == omx_message::EVENT
+            && msg.u.event_data.event == OMX_EventCmdComplete
+            && msg.u.event_data.data1 == OMX_CommandStateSet
+            && msg.u.event_data.data2 == OMX_StateIdle,
+           "Component did not properly transition to idle state "
+           "after all input and output buffers were allocated.");
+
+    // Initiate transition Idle->Executing
+    err = mOMX->sendCommand(node, OMX_CommandStateSet, OMX_StateExecuting);
+    EXPECT_SUCCESS(err, "sendCommand(go-to-Executing)");
+
+    err = dequeueMessageForNode(node, &msg, DEFAULT_TIMEOUT);
+    EXPECT(err == OK
+            && msg.type == omx_message::EVENT
+            && msg.u.event_data.event == OMX_EventCmdComplete
+            && msg.u.event_data.data1 == OMX_CommandStateSet
+            && msg.u.event_data.data2 == OMX_StateExecuting,
+           "Component did not properly transition from idle to "
+           "executing state.");
+
+    for (size_t i = 0; i < outputBuffers.size(); ++i) {
+        err = mOMX->fillBuffer(node, outputBuffers[i].mID);
+        EXPECT_SUCCESS(err, "fillBuffer");
+
+        outputBuffers.editItemAt(i).mFlags |= kBufferBusy;
+    }
+
+    err = mOMX->sendCommand(node, OMX_CommandFlush, 1);
+    EXPECT_SUCCESS(err, "sendCommand(flush-output-port)");
+
+    err = dequeueMessageForNodeIgnoringBuffers(
+            node, &inputBuffers, &outputBuffers, &msg, DEFAULT_TIMEOUT);
+    EXPECT(err == OK
+            && msg.type == omx_message::EVENT
+            && msg.u.event_data.event == OMX_EventCmdComplete
+            && msg.u.event_data.data1 == OMX_CommandFlush
+            && msg.u.event_data.data2 == 1,
+           "Component did not properly acknowledge flushing the output port.");
+
+    for (size_t i = 0; i < outputBuffers.size(); ++i) {
+        EXPECT((outputBuffers[i].mFlags & kBufferBusy) == 0,
+               "Not all output buffers have been returned to us by the time "
+               "we received the flush-complete notification.");
+    }
+
+    for (size_t i = 0; i < outputBuffers.size(); ++i) {
+        err = mOMX->fillBuffer(node, outputBuffers[i].mID);
+        EXPECT_SUCCESS(err, "fillBuffer");
+
+        outputBuffers.editItemAt(i).mFlags |= kBufferBusy;
+    }
+
+    // Initiate transition Executing->Idle
+    err = mOMX->sendCommand(node, OMX_CommandStateSet, OMX_StateIdle);
+    EXPECT_SUCCESS(err, "sendCommand(go-to-Idle)");
+
+    err = dequeueMessageForNodeIgnoringBuffers(
+            node, &inputBuffers, &outputBuffers, &msg, DEFAULT_TIMEOUT);
+    EXPECT(err == OK
+            && msg.type == omx_message::EVENT
+            && msg.u.event_data.event == OMX_EventCmdComplete
+            && msg.u.event_data.data1 == OMX_CommandStateSet
+            && msg.u.event_data.data2 == OMX_StateIdle,
+           "Component did not properly transition to from executing to "
+           "idle state.");
+
+    for (size_t i = 0; i < inputBuffers.size(); ++i) {
+        EXPECT((inputBuffers[i].mFlags & kBufferBusy) == 0,
+                "Not all input buffers have been returned to us by the "
+                "time we received the transition-to-idle complete "
+                "notification.");
+    }
+
+    for (size_t i = 0; i < outputBuffers.size(); ++i) {
+        EXPECT((outputBuffers[i].mFlags & kBufferBusy) == 0,
+                "Not all output buffers have been returned to us by the "
+                "time we received the transition-to-idle complete "
+                "notification.");
+    }
+
+    // Initiate transition Idle->Loaded
+    err = mOMX->sendCommand(node, 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);
+    CHECK_EQ(err, TIMED_OUT);
+
+    for (size_t i = 0; i < inputBuffers.size(); ++i) {
+        err = mOMX->freeBuffer(node, 0, inputBuffers[i].mID);
+        EXPECT_SUCCESS(err, "freeBuffer");
+    }
+
+    err = dequeueMessageForNode(node, &msg, DEFAULT_TIMEOUT);
+    CHECK_EQ(err, TIMED_OUT);
+
+    for (size_t i = 0; i < outputBuffers.size(); ++i) {
+        err = mOMX->freeBuffer(node, 1, outputBuffers[i].mID);
+        EXPECT_SUCCESS(err, "freeBuffer");
+    }
+
+    err = dequeueMessageForNode(node, &msg, DEFAULT_TIMEOUT);
+    EXPECT(err == OK
+            && msg.type == omx_message::EVENT
+            && msg.u.event_data.event == OMX_EventCmdComplete
+            && msg.u.event_data.data1 == OMX_CommandStateSet
+            && msg.u.event_data.data2 == OMX_StateLoaded,
+           "Component did not properly transition to from idle to "
+           "loaded state after freeing all input and output buffers.");
+
+    err = mOMX->freeNode(node);
+    EXPECT_SUCCESS(err, "freeNode");
+
+    reaper.disarm();
+
+    node = 0;
+
+    return OK;
+}
+
+static const char *GetMimeFromComponentRole(const char *componentRole) {
+    struct RoleToMime {
+        const char *mRole;
+        const char *mMime;
+    };
+    const RoleToMime kRoleToMime[] = {
+        { "video_decoder.avc", "video/avc" },
+        { "video_decoder.mpeg4", "video/mp4v-es" },
+        { "video_decoder.h263", "video/3gpp" },
+
+        // we appear to use this as a synonym to amrnb.
+        { "audio_decoder.amr", "audio/3gpp" },
+
+        { "audio_decoder.amrnb", "audio/3gpp" },
+        { "audio_decoder.amrwb", "audio/amr-wb" },
+        { "audio_decoder.aac", "audio/mp4a-latm" },
+        { "audio_decoder.mp3", "audio/mpeg" }
+    };
+
+    for (size_t i = 0; i < sizeof(kRoleToMime) / sizeof(kRoleToMime[0]); ++i) {
+        if (!strcmp(componentRole, kRoleToMime[i].mRole)) {
+            return kRoleToMime[i].mMime;
+        }
+    }
+
+    return NULL;
+}
+
+static const char *GetURLForMime(const char *mime) {
+    struct MimeToURL {
+        const char *mMime;
+        const char *mURL;
+    };
+    static const MimeToURL kMimeToURL[] = {
+        { "video/avc",
+          "file:///sdcard/media_api/video/H264_AAC.3gp" },
+        { "video/mp4v-es", "file:///sdcard/media_api/video/gingerkids.MP4" },
+        { "video/3gpp",
+          "file:///sdcard/media_api/video/H263_500_AMRNB_12.3gp" },
+        { "audio/3gpp",
+          "file:///sdcard/media_api/video/H263_500_AMRNB_12.3gp" },
+        { "audio/amr-wb",
+          "file:///sdcard/media_api/music_perf/AMRWB/"
+          "NIN_AMR-WB_15.85kbps_16kbps.amr" },
+        { "audio/mp4a-latm",
+          "file:///sdcard/media_api/music_perf/AAC/"
+          "WC_AAC_80kbps_32khz_Stereo_1pCBR_SSE.mp4" },
+        { "audio/mpeg",
+          "file:///sdcard/media_api/music_perf/MP3/"
+          "WC_256kbps_44.1khz_mono_CBR_DPA.mp3" }
+    };
+
+    for (size_t i = 0; i < sizeof(kMimeToURL) / sizeof(kMimeToURL[0]); ++i) {
+        if (!strcasecmp(kMimeToURL[i].mMime, mime)) {
+            return kMimeToURL[i].mURL;
+        }
+    }
+
+    return NULL;
+}
+
+static sp<MediaSource> CreateSourceForMime(const char *mime) {
+    const char *url = GetURLForMime(mime);
+    CHECK(url != NULL);
+
+    sp<MediaExtractor> extractor = MediaExtractor::CreateFromURI(url);
+
+    CHECK(extractor != NULL);
+
+    for (size_t i = 0; i < extractor->countTracks(); ++i) {
+        sp<MetaData> meta = extractor->getTrackMetaData(i);
+        CHECK(meta != NULL);
+
+        const char *trackMime;
+        CHECK(meta->findCString(kKeyMIMEType, &trackMime));
+
+        if (!strcasecmp(mime, trackMime)) {
+            return extractor->getTrack(i);
+        }
+    }
+
+    return NULL;
+}
+
+static double uniform_rand() {
+    return (double)rand() / RAND_MAX;
+}
+
+static bool CloseEnough(int64_t time1Us, int64_t time2Us) {
+#if 0
+    int64_t diff = time1Us - time2Us;
+    if (diff < 0) {
+        diff = -diff;
+    }
+
+    return diff <= 50000;
+#else
+    return time1Us == time2Us;
+#endif
+}
+
+status_t Harness::testSeek(
+        const char *componentName, const char *componentRole) {
+    bool isEncoder =
+        !strncmp(componentRole, "audio_encoder.", 14)
+        || !strncmp(componentRole, "video_encoder.", 14);
+
+    if (isEncoder) {
+        // Not testing seek behaviour for encoders.
+
+        printf("  * Not testing seek functionality for encoders.\n");
+        return OK;
+    }
+
+    const char *mime = GetMimeFromComponentRole(componentRole);
+
+    if (!mime) {
+        LOGI("Cannot perform seek test with this componentRole (%s)",
+             componentRole);
+
+        return OK;
+    }
+
+    sp<MediaSource> source = CreateSourceForMime(mime);
+
+    sp<MediaSource> seekSource = CreateSourceForMime(mime);
+    CHECK_EQ(seekSource->start(), OK);
+
+    sp<MediaSource> codec = OMXCodec::Create(
+            mOMX, source->getFormat(), false /* createEncoder */,
+            source, componentName);
+
+    CHECK(codec != NULL);
+
+    CHECK_EQ(codec->start(), OK);
+
+    int64_t durationUs;
+    CHECK(source->getFormat()->findInt64(kKeyDuration, &durationUs));
+
+    LOGI("stream duration is %lld us (%.2f secs)",
+         durationUs, durationUs / 1E6);
+
+    static const int32_t kNumIterations = 5000;
+
+    for (int32_t i = 0; i < kNumIterations; ++i) {
+        int64_t requestedSeekTimeUs;
+        int64_t actualSeekTimeUs;
+        MediaSource::ReadOptions options;
+
+        double r = uniform_rand();
+
+        if (r < 0.5) {
+            // 50% chance of just continuing to decode from last position.
+
+            requestedSeekTimeUs = -1;
+
+            LOGI("requesting linear read");
+        } else {
+            if (r < 0.55) {
+                // 5% chance of seeking beyond end of stream.
+
+                requestedSeekTimeUs = durationUs;
+
+                LOGI("requesting seek beyond EOF");
+            } else {
+                requestedSeekTimeUs =
+                    (int64_t)(uniform_rand() * durationUs);
+
+                LOGI("requesting seek to %lld us (%.2f secs)",
+                     requestedSeekTimeUs, requestedSeekTimeUs / 1E6);
+            }
+
+            MediaBuffer *buffer;
+            options.setSeekTo(requestedSeekTimeUs);
+            if (seekSource->read(&buffer, &options) != OK) {
+                CHECK_EQ(buffer, NULL);
+                actualSeekTimeUs = -1;
+            } else {
+                CHECK(buffer != NULL);
+                CHECK(buffer->meta_data()->findInt64(kKeyTime, &actualSeekTimeUs));
+                CHECK(actualSeekTimeUs >= 0);
+
+                buffer->release();
+                buffer = NULL;
+            }
+
+            LOGI("nearest keyframe is at %lld us (%.2f secs)",
+                 actualSeekTimeUs, actualSeekTimeUs / 1E6);
+        }
+
+        status_t err;
+        MediaBuffer *buffer;
+        for (;;) {
+            err = codec->read(&buffer, &options);
+            options.clearSeekTo();
+            if (err == INFO_FORMAT_CHANGED) {
+                CHECK_EQ(buffer, NULL);
+                continue;
+            }
+            if (err == OK) {
+                CHECK(buffer != NULL);
+                if (buffer->range_length() == 0) {
+                    buffer->release();
+                    buffer = NULL;
+                    continue;
+                }
+            } else {
+                CHECK_EQ(buffer, NULL);
+            }
+
+            break;
+        }
+
+        if (requestedSeekTimeUs < 0) {
+            // Linear read.
+            if (err != OK) {
+                CHECK_EQ(buffer, NULL);
+            } else {
+                CHECK(buffer != NULL);
+                buffer->release();
+                buffer = NULL;
+            }
+        } else if (actualSeekTimeUs < 0) {
+            CHECK(err != OK);
+            CHECK_EQ(buffer, NULL);
+        } else {
+            EXPECT(err == OK,
+                   "Expected a valid buffer to be returned from "
+                   "OMXCodec::read.");
+            CHECK(buffer != NULL);
+
+            int64_t bufferTimeUs;
+            CHECK(buffer->meta_data()->findInt64(kKeyTime, &bufferTimeUs));
+            if (!CloseEnough(bufferTimeUs, actualSeekTimeUs)) {
+                printf("\n  * Attempted seeking to %lld us (%.2f secs)",
+                       requestedSeekTimeUs, requestedSeekTimeUs / 1E6);
+                printf("\n  * Nearest keyframe is at %lld us (%.2f secs)",
+                       actualSeekTimeUs, actualSeekTimeUs / 1E6);
+                printf("\n  * Returned buffer was at %lld us (%.2f secs)\n\n",
+                       bufferTimeUs, bufferTimeUs / 1E6);
+
+                buffer->release();
+                buffer = NULL;
+
+                CHECK_EQ(codec->stop(), OK);
+
+                return UNKNOWN_ERROR;
+            }
+
+            buffer->release();
+            buffer = NULL;
+        }
+    }
+
+    CHECK_EQ(codec->stop(), OK);
+
+    return OK;
+}
+
+status_t Harness::test(
+        const char *componentName, const char *componentRole) {
+    printf("testing %s [%s] ... ", componentName, componentRole);
+    LOGI("testing %s [%s].", componentName, componentRole);
+
+    status_t err1 = testStateTransitions(componentName, componentRole);
+    status_t err2 = testSeek(componentName, componentRole);
+
+    if (err1 != OK) {
+        return err1;
+    }
+
+    return err2;
+}
+
+status_t Harness::testAll() {
+    List<IOMX::ComponentInfo> componentInfos;
+    status_t err = mOMX->listNodes(&componentInfos);
+    EXPECT_SUCCESS(err, "listNodes");
+
+    for (List<IOMX::ComponentInfo>::iterator it = componentInfos.begin();
+         it != componentInfos.end(); ++it) {
+        const IOMX::ComponentInfo &info = *it;
+        const char *componentName = info.mName.string();
+
+        for (List<String8>::const_iterator role_it = info.mRoles.begin();
+             role_it != info.mRoles.end(); ++role_it) {
+            const char *componentRole = (*role_it).string();
+
+            err = test(componentName, componentRole);
+
+            if (err == OK) {
+                printf("OK\n");
+            }
+        }
+    }
+
+    return OK;
+}
+
+}  // namespace android
+
+static void usage(const char *me) {
+    fprintf(stderr, "usage: %s\n"
+                    "  -h(elp)  Show this information\n"
+                    "  -s(eed)  Set the random seed\n"
+                    "    [ component role ]\n\n"
+                    "When launched without specifying a specific component "
+                    "and role, tool will test all available OMX components "
+                    "in all their supported roles. To determine available "
+                    "component names, use \"stagefright -l\"\n"
+                    "It's also a good idea to run a separate \"adb logcat\""
+                    " for additional debug and progress information.", me);
+
+    exit(0);
+}
+
+int main(int argc, char **argv) {
+    using namespace android;
+
+    android::ProcessState::self()->startThreadPool();
+    DataSource::RegisterDefaultSniffers();
+
+    const char *me = argv[0];
+
+    unsigned long seed = 0xdeadbeef;
+
+    int res;
+    while ((res = getopt(argc, argv, "hs:")) >= 0) {
+        switch (res) {
+            case 's':
+            {
+                char *end;
+                unsigned long x = strtoul(optarg, &end, 10);
+
+                if (*end != '\0' || end == optarg) {
+                    fprintf(stderr, "Malformed seed.\n");
+                    return 1;
+                }
+
+                seed = x;
+                break;
+            }
+
+            case '?':
+                fprintf(stderr, "\n");
+                // fall through
+
+            case 'h':
+            default:
+            {
+                usage(me);
+                exit(1);
+                break;
+            }
+        }
+    }
+
+    argc -= optind;
+    argv += optind;
+
+    printf("To reproduce the conditions for this test, launch "
+           "with \"%s -s %lu\"\n", me, seed);
+
+    srand(seed);
+
+    sp<Harness> h = new Harness;
+    CHECK_EQ(h->initCheck(), OK);
+
+    if (argc == 0) {
+        h->testAll();
+    } else if (argc == 2) {
+        if (h->test(argv[0], argv[1]) == OK) {
+            printf("OK\n");
+        }
+    }
+
+    return 0;
+}
diff --git a/media/libstagefright/omx/tests/OMXHarness.h b/media/libstagefright/omx/tests/OMXHarness.h
new file mode 100644
index 0000000..bb8fd0c
--- /dev/null
+++ b/media/libstagefright/omx/tests/OMXHarness.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OMX_HARNESS_H_
+
+#define OMX_HARNESS_H_
+
+#include <media/IOMX.h>
+#include <utils/List.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+
+#include <OMX_Component.h>
+
+namespace android {
+
+class MemoryDealer;
+
+struct Harness : public BnOMXObserver {
+    enum BufferFlags {
+        kBufferBusy = 1
+    };
+    struct Buffer {
+        IOMX::buffer_id mID;
+        sp<IMemory> mMemory;
+        uint32_t mFlags;
+    };
+
+    Harness();
+
+    status_t initCheck() const;
+
+    status_t dequeueMessageForNode(
+            IOMX::node_id node, 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);
+
+    status_t allocatePortBuffers(
+            const sp<MemoryDealer> &dealer,
+            IOMX::node_id node, OMX_U32 portIndex,
+            Vector<Buffer> *buffers);
+
+    status_t setRole(IOMX::node_id node, const char *role);
+
+    status_t testStateTransitions(
+            const char *componentName, const char *componentRole);
+
+    status_t testSeek(
+            const char *componentName, const char *componentRole);
+
+    status_t test(
+            const char *componentName, const char *componentRole);
+
+    status_t testAll();
+
+    virtual void onMessage(const omx_message &msg);
+
+protected:
+    virtual ~Harness();
+
+private:
+    friend struct NodeReaper;
+
+    Mutex mLock;
+
+    status_t mInitCheck;
+    sp<IOMX> mOMX;
+    List<omx_message> mMessageQueue;
+    Condition mMessageAddedCondition;
+
+    status_t initOMX();
+
+    bool handleBufferMessage(
+            const omx_message &msg,
+            Vector<Buffer> *inputBuffers,
+            Vector<Buffer> *outputBuffers);
+
+    Harness(const Harness &);
+    Harness &operator=(const Harness &);
+};
+
+}  // namespace android
+
+#endif  // OMX_HARNESS_H_
