Implementation of the stagefright hardware api interface.
diff --git a/libstagefrighthw/Android.mk b/libstagefrighthw/Android.mk
new file mode 100644
index 0000000..37757c4
--- /dev/null
+++ b/libstagefrighthw/Android.mk
@@ -0,0 +1,25 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+    stagefright_overlay_output.cpp \
+    TIHardwareRenderer.cpp
+
+LOCAL_CFLAGS := $(PV_CFLAGS_MINUS_VISIBILITY)
+
+LOCAL_C_INCLUDES:= \
+        $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
+        $(TOP)/hardware/ti/omap3/liboverlay
+
+LOCAL_SHARED_LIBRARIES :=       \
+        libbinder               \
+        libutils                \
+        libcutils               \
+        libui                   \
+
+LOCAL_MODULE := libstagefrighthw
+
+LOCAL_PRELINK_MODULE:= false
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/libstagefrighthw/TIHardwareRenderer.cpp b/libstagefrighthw/TIHardwareRenderer.cpp
new file mode 100644
index 0000000..53818d6
--- /dev/null
+++ b/libstagefrighthw/TIHardwareRenderer.cpp
@@ -0,0 +1,131 @@
+/*
+ * 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_TAG "TIHardwareRenderer"
+#include <utils/Log.h>
+
+#include "TIHardwareRenderer.h"
+
+#include <media/stagefright/MediaDebug.h>
+#include <ui/ISurface.h>
+#include <ui/Overlay.h>
+
+#include "v4l2_utils.h"
+
+#define CACHEABLE_BUFFERS 0x1
+
+namespace android {
+
+////////////////////////////////////////////////////////////////////////////////
+
+TIHardwareRenderer::TIHardwareRenderer(
+        const sp<ISurface> &surface,
+        size_t displayWidth, size_t displayHeight,
+        size_t decodedWidth, size_t decodedHeight)
+    : mISurface(surface),
+      mDisplayWidth(displayWidth),
+      mDisplayHeight(displayHeight),
+      mDecodedWidth(decodedWidth),
+      mDecodedHeight(decodedHeight),
+      mFrameSize(mDecodedWidth * mDecodedHeight * 2),
+      mIsFirstFrame(true),
+      mIndex(0) {
+    CHECK(mISurface.get() != NULL);
+    CHECK(mDecodedWidth > 0);
+    CHECK(mDecodedHeight > 0);
+
+    sp<OverlayRef> ref = mISurface->createOverlay(
+            mDisplayWidth, mDisplayHeight, OVERLAY_FORMAT_CbYCrY_422_I);
+
+    if (ref.get() == NULL) {
+        LOGE("Unable to create the overlay!");
+        return;
+    }
+
+    mOverlay = new Overlay(ref);
+    mOverlay->setParameter(CACHEABLE_BUFFERS, 0);
+
+    for (size_t i = 0; i < (size_t)mOverlay->getBufferCount(); ++i) {
+        mapping_data_t *data =
+            (mapping_data_t *)mOverlay->getBufferAddress((void *)i);
+
+        mOverlayAddresses.push(data->ptr);
+    }
+}
+
+TIHardwareRenderer::~TIHardwareRenderer() {
+    if (mOverlay.get() != NULL) {
+        mOverlay->destroy();
+        mOverlay.clear();
+
+        // XXX apparently destroying an overlay is an asynchronous process...
+        sleep(1);
+    }
+}
+
+void TIHardwareRenderer::render(
+        const void *data, size_t size, void *platformPrivate) {
+    // CHECK_EQ(size, mFrameSize);
+
+    if (mOverlay.get() == NULL) {
+        return;
+    }
+
+#if 0
+    size_t i = 0;
+    for (; i < mOverlayAddresses.size(); ++i) {
+        if (mOverlayAddresses[i] == data) {
+            break;
+        }
+
+        if (mIsFirstFrame) {
+            LOGI("overlay buffer #%d: %p", i, mOverlayAddresses[i]);
+        }
+    }
+
+    if (i == mOverlayAddresses.size()) {
+        LOGE("No suitable overlay buffer found.");
+        return;
+    }
+
+    mOverlay->queueBuffer((void *)i);
+
+    overlay_buffer_t overlay_buffer;
+    if (!mIsFirstFrame) {
+        CHECK_EQ(mOverlay->dequeueBuffer(&overlay_buffer), OK);
+    } else {
+        mIsFirstFrame = false;
+    }
+#else
+    memcpy(mOverlayAddresses[mIndex], data, size);
+
+    mOverlay->queueBuffer((void *)mIndex);
+
+    if (++mIndex == mOverlayAddresses.size()) {
+        mIndex = 0;
+    }
+
+    overlay_buffer_t overlay_buffer;
+    if (!mIsFirstFrame) {
+        CHECK_EQ(mOverlay->dequeueBuffer(&overlay_buffer), OK);
+    } else {
+        mIsFirstFrame = false;
+    }
+#endif
+}
+
+}  // namespace android
+
diff --git a/libstagefrighthw/TIHardwareRenderer.h b/libstagefrighthw/TIHardwareRenderer.h
new file mode 100644
index 0000000..ef42648
--- /dev/null
+++ b/libstagefrighthw/TIHardwareRenderer.h
@@ -0,0 +1,59 @@
+/*
+ * 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 TI_HARDWARE_RENDERER_H_
+
+#define TI_HARDWARE_RENDERER_H_
+
+#include <media/stagefright/VideoRenderer.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class ISurface;
+class Overlay;
+
+class TIHardwareRenderer : public VideoRenderer {
+public:
+    TIHardwareRenderer(
+            const sp<ISurface> &surface,
+            size_t displayWidth, size_t displayHeight,
+            size_t decodedWidth, size_t decodedHeight);
+
+    virtual ~TIHardwareRenderer();
+
+    virtual void render(
+            const void *data, size_t size, void *platformPrivate);
+
+private:
+    sp<ISurface> mISurface;
+    size_t mDisplayWidth, mDisplayHeight;
+    size_t mDecodedWidth, mDecodedHeight;
+    size_t mFrameSize;
+    sp<Overlay> mOverlay;
+    Vector<void *> mOverlayAddresses;
+    bool mIsFirstFrame;
+    size_t mIndex;
+
+    TIHardwareRenderer(const TIHardwareRenderer &);
+    TIHardwareRenderer &operator=(const TIHardwareRenderer &);
+};
+
+}  // namespace android
+
+#endif  // TI_HARDWARE_RENDERER_H_
+
diff --git a/libstagefrighthw/stagefright_overlay_output.cpp b/libstagefrighthw/stagefright_overlay_output.cpp
new file mode 100644
index 0000000..263d55f
--- /dev/null
+++ b/libstagefrighthw/stagefright_overlay_output.cpp
@@ -0,0 +1,26 @@
+#include <media/stagefright/HardwareAPI.h>
+
+#include "TIHardwareRenderer.h"
+
+using android::sp;
+using android::ISurface;
+using android::VideoRenderer;
+
+VideoRenderer *createRenderer(
+        const sp<ISurface> &surface,
+        const char *componentName,
+        OMX_COLOR_FORMATTYPE colorFormat,
+        size_t displayWidth, size_t displayHeight,
+        size_t decodedWidth, size_t decodedHeight) {
+    using android::TIHardwareRenderer;
+
+    if (colorFormat == OMX_COLOR_FormatCbYCrY
+            && !strcmp(componentName, "OMX.TI.Video.Decoder")) {
+        return new TIHardwareRenderer(
+                surface, displayWidth, displayHeight,
+                decodedWidth, decodedHeight);
+    }
+
+    return NULL;
+}
+