Merge "Multiple changes to ACodec/codec tools:"
diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp
index 289665f..ddd64ec 100644
--- a/cmds/stagefright/sf2.cpp
+++ b/cmds/stagefright/sf2.cpp
@@ -29,6 +29,7 @@
 #include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MediaSource.h>
 #include <media/stagefright/MetaData.h>
+#include <media/stagefright/NativeWindowWrapper.h>
 #include <media/stagefright/Utils.h>
 
 #include <surfaceflinger/ISurfaceComposer.h>
@@ -39,10 +40,12 @@
 using namespace android;
 
 struct Controller : public AHandler {
-    Controller(const char *uri, bool decodeAudio, const sp<Surface> &surface)
+    Controller(const char *uri, bool decodeAudio,
+               const sp<Surface> &surface, bool renderToSurface)
         : mURI(uri),
           mDecodeAudio(decodeAudio),
           mSurface(surface),
+          mRenderToSurface(renderToSurface),
           mCodec(new ACodec) {
         CHECK(!mDecodeAudio || mSurface == NULL);
     }
@@ -97,7 +100,8 @@
                 sp<AMessage> format = makeFormat(mSource->getFormat());
 
                 if (mSurface != NULL) {
-                    format->setObject("surface", mSurface);
+                    format->setObject(
+                            "native-window", new NativeWindowWrapper(mSurface));
                 }
 
                 mCodec->initiateSetup(format);
@@ -220,6 +224,7 @@
     AString mURI;
     bool mDecodeAudio;
     sp<Surface> mSurface;
+    bool mRenderToSurface;
     sp<ACodec> mCodec;
     sp<MediaSource> mSource;
 
@@ -451,7 +456,7 @@
                 inBuffer->release();
                 inBuffer = NULL;
 
-                // break;  // Don't coalesce
+                break;  // Don't coalesce
             }
 
             LOGV("coalesced %d input buffers", n);
@@ -479,6 +484,10 @@
         sp<AMessage> reply;
         CHECK(msg->findMessage("reply", &reply));
 
+        if (mRenderToSurface) {
+            reply->setInt32("render", 1);
+        }
+
         reply->post();
     }
 
@@ -491,7 +500,8 @@
     fprintf(stderr, "       -a(udio)\n");
 
     fprintf(stderr,
-            "       -s(surface) Allocate output buffers on a surface.\n");
+            "       -S(urface) Allocate output buffers on a surface.\n"
+            "       -R(ender)  Render surface-allocated buffers.\n");
 }
 
 int main(int argc, char **argv) {
@@ -499,18 +509,23 @@
 
     bool decodeAudio = false;
     bool useSurface = false;
+    bool renderToSurface = false;
 
     int res;
-    while ((res = getopt(argc, argv, "has")) >= 0) {
+    while ((res = getopt(argc, argv, "haSR")) >= 0) {
         switch (res) {
             case 'a':
                 decodeAudio = true;
                 break;
 
-            case 's':
+            case 'S':
                 useSurface = true;
                 break;
 
+            case 'R':
+                renderToSurface = true;
+                break;
+
             case '?':
             case 'h':
             default:
@@ -562,7 +577,9 @@
         CHECK(surface != NULL);
     }
 
-    sp<Controller> controller = new Controller(argv[0], decodeAudio, surface);
+    sp<Controller> controller =
+        new Controller(argv[0], decodeAudio, surface, renderToSurface);
+
     looper->registerHandler(controller);
 
     controller->startAsync();
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 589cefd..92331a1 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -79,6 +79,13 @@
     // from MediaBufferObserver
     virtual void signalBufferReturned(MediaBuffer *buffer);
 
+    // for use by ACodec
+    static void findMatchingCodecs(
+            const char *mime,
+            bool createEncoder, const char *matchComponentName,
+            uint32_t flags,
+            Vector<String8> *matchingCodecs);
+
 protected:
     virtual ~OMXCodec();
 
@@ -311,12 +318,6 @@
     static uint32_t getComponentQuirks(
             const char *componentName, bool isEncoder);
 
-    static void findMatchingCodecs(
-            const char *mime,
-            bool createEncoder, const char *matchComponentName,
-            uint32_t flags,
-            Vector<String8> *matchingCodecs);
-
     void restorePatchedDataPointer(BufferInfo *info);
 
     status_t applyRotation();
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index d628301..513eda8 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -29,6 +29,7 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/NativeWindowWrapper.h>
 #include <media/stagefright/OMXClient.h>
+#include <media/stagefright/OMXCodec.h>
 
 #include <surfaceflinger/Surface.h>
 #include <gui/SurfaceTextureClient.h>
@@ -401,11 +402,22 @@
         CHECK(mem.get() != NULL);
 
         IOMX::buffer_id buffer;
-#if 0
-        err = mOMX->allocateBufferWithBackup(mNode, portIndex, mem, &buffer);
-#else
-        err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
-#endif
+
+        if (!strcasecmp(
+                    mComponentName.c_str(), "OMX.TI.DUCATI1.VIDEO.DECODER")) {
+            if (portIndex == kPortIndexInput && i == 0) {
+                // Only log this warning once per allocation round.
+
+                LOGW("OMX.TI.DUCATI1.VIDEO.DECODER requires the use of "
+                     "OMX_AllocateBuffer instead of the preferred "
+                     "OMX_UseBuffer. Vendor must fix this.");
+            }
+
+            err = mOMX->allocateBufferWithBackup(
+                    mNode, portIndex, mem, &buffer);
+        } else {
+            err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
+        }
 
         if (err != OK) {
             return err;
@@ -891,6 +903,7 @@
     CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
            || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
            || format.eColorFormat == OMX_COLOR_FormatCbYCrY
+           || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
            || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
 
     return mOMX->setParameter(
@@ -1639,27 +1652,33 @@
     AString mime;
     CHECK(msg->findString("mime", &mime));
 
-    AString componentName;
-
-    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
-        componentName = "OMX.Nvidia.h264.decode";
-    } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
-        componentName = "OMX.google.aac.decoder";
-    } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_MPEG)) {
-        componentName = "OMX.Nvidia.mp3.decoder";
-    } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG2)) {
-        componentName = "OMX.Nvidia.mpeg2v.decode";
-    } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG4)) {
-        componentName = "OMX.google.mpeg4.decoder";
-    } else {
-        TRESPASS();
-    }
+    Vector<String8> matchingCodecs;
+    OMXCodec::findMatchingCodecs(
+            mime.c_str(),
+            false, // createEncoder
+            NULL,  // matchComponentName
+            0,     // flags
+            &matchingCodecs);
 
     sp<CodecObserver> observer = new CodecObserver;
+    IOMX::node_id node = NULL;
 
-    IOMX::node_id node;
-    CHECK_EQ(omx->allocateNode(componentName.c_str(), observer, &node),
-             (status_t)OK);
+    AString componentName;
+
+    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
+            ++matchIndex) {
+        componentName = matchingCodecs.itemAt(matchIndex).string();
+
+        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
+
+        if (err == OK) {
+            break;
+        }
+
+        node = NULL;
+    }
+
+    CHECK(node != NULL);
 
     sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id());
     observer->setNotificationMessage(notify);