Merge changes I3aa5872e,I914bcc88,Icc6d023f,Ic262482a

* changes:
  stagefright: use small timeout for input buffer in SimpleDecodingSource
  stagefright: CodecCapabilities: fix missing capabilities
  stagefright: ACodec: remove infinite loops
  stagefright: ACodec: query color format support on specific port
diff --git a/include/media/MediaCodecInfo.h b/include/media/MediaCodecInfo.h
index 84faa2f..ac5b075 100644
--- a/include/media/MediaCodecInfo.h
+++ b/include/media/MediaCodecInfo.h
@@ -122,8 +122,8 @@
     void addQuirk(const char *name);
     status_t addMime(const char *mime);
     status_t updateMime(const char *mime);
-    // after this call Capabilities will be owned by MediaCodecInfo
-    status_t setCapabilities(const sp<Capabilities> &caps);
+
+    status_t initializeCapabilities(const sp<Capabilities> &caps);
     void addDetail(const AString &key, const AString &value);
     void addFeature(const AString &key, int32_t value);
     void addFeature(const AString &key, const char *value);
diff --git a/media/libmedia/MediaCodecInfo.cpp b/media/libmedia/MediaCodecInfo.cpp
index 3b53f4c..06abd8d 100644
--- a/media/libmedia/MediaCodecInfo.cpp
+++ b/media/libmedia/MediaCodecInfo.cpp
@@ -238,8 +238,15 @@
     }
 }
 
-status_t MediaCodecInfo::setCapabilities(const sp<Capabilities> &caps) {
-    mCurrentCaps = caps;
+status_t MediaCodecInfo::initializeCapabilities(const sp<Capabilities> &caps) {
+    // TRICKY: copy data to mCurrentCaps as it is a reference to
+    // an element of the capabilites map.
+    mCurrentCaps->mColorFormats.clear();
+    mCurrentCaps->mColorFormats.appendVector(caps->mColorFormats);
+    mCurrentCaps->mProfileLevels.clear();
+    mCurrentCaps->mProfileLevels.appendVector(caps->mProfileLevels);
+    mCurrentCaps->mFlags = caps->mFlags;
+    mCurrentCaps->mDetails = caps->mDetails;
     return OK;
 }
 
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index cb6b22f..10734e4 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -55,6 +55,10 @@
 
 namespace android {
 
+enum {
+    kMaxIndicesToCheck = 32, // used when enumerating supported formats and profiles
+};
+
 // OMX errors are directly mapped into status_t range if
 // there is no corresponding MediaError status code.
 // Use the statusFromOMXError(int32_t omxError) function.
@@ -2278,9 +2282,8 @@
     InitOMXParams(&format);
 
     format.nPortIndex = portIndex;
-    for (OMX_U32 index = 0;; ++index) {
+    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
         format.nIndex = index;
-
         status_t err = mOMX->getParameter(
                 mNode, OMX_IndexParamAudioPortFormat,
                 &format, sizeof(format));
@@ -2292,6 +2295,13 @@
         if (format.eEncoding == desiredFormat) {
             break;
         }
+
+        if (index == kMaxIndicesToCheck) {
+            ALOGW("[%s] stopping checking formats after %u: %s(%x)",
+                    mComponentName.c_str(), index,
+                    asString(format.eEncoding), format.eEncoding);
+            return ERROR_UNSUPPORTED;
+        }
     }
 
     return mOMX->setParameter(
@@ -2711,8 +2721,7 @@
     format.nIndex = 0;
     bool found = false;
 
-    OMX_U32 index = 0;
-    for (;;) {
+    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
         format.nIndex = index;
         status_t err = mOMX->getParameter(
                 mNode, OMX_IndexParamVideoPortFormat,
@@ -2757,7 +2766,12 @@
             break;
         }
 
-        ++index;
+        if (index == kMaxIndicesToCheck) {
+            ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)",
+                    mComponentName.c_str(), index,
+                    asString(format.eCompressionFormat), format.eCompressionFormat,
+                    asString(format.eColorFormat), format.eColorFormat);
+        }
     }
 
     if (!found) {
@@ -3630,7 +3644,8 @@
     InitOMXParams(&params);
     params.nPortIndex = kPortIndexOutput;
 
-    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
+    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
+        params.nProfileIndex = index;
         status_t err = mOMX->getParameter(
                 mNode,
                 OMX_IndexParamVideoProfileLevelQuerySupported,
@@ -3647,7 +3662,14 @@
         if (profile == supportedProfile && level <= supportedLevel) {
             return OK;
         }
+
+        if (index == kMaxIndicesToCheck) {
+            ALOGW("[%s] stopping checking profiles after %u: %x/%x",
+                    mComponentName.c_str(), index,
+                    params.eProfile, params.eLevel);
+        }
     }
+    return ERROR_UNSUPPORTED;
 }
 
 status_t ACodec::configureBitrate(
@@ -6904,7 +6926,8 @@
         InitOMXParams(&param);
         param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
 
-        for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
+        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
+            param.nProfileIndex = index;
             status_t err = omx->getParameter(
                     node, OMX_IndexParamVideoProfileLevelQuerySupported,
                     &param, sizeof(param));
@@ -6912,6 +6935,12 @@
                 break;
             }
             builder->addProfileLevel(param.eProfile, param.eLevel);
+
+            if (index == kMaxIndicesToCheck) {
+                ALOGW("[%s] stopping checking profiles after %u: %x/%x",
+                        name.c_str(), index,
+                        param.eProfile, param.eLevel);
+            }
         }
 
         // Color format query
@@ -6919,9 +6948,10 @@
         // prefix "flexible" standard ones with the flexible equivalent
         OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
         InitOMXParams(&portFormat);
-        param.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
+        portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
         Vector<uint32_t> supportedColors; // shadow copy to check for duplicates
-        for (portFormat.nIndex = 0;; ++portFormat.nIndex)  {
+        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
+            portFormat.nIndex = index;
             status_t err = omx->getParameter(
                     node, OMX_IndexParamVideoPortFormat,
                     &portFormat, sizeof(portFormat));
@@ -6947,6 +6977,12 @@
             }
             supportedColors.push(portFormat.eColorFormat);
             builder->addColorFormat(portFormat.eColorFormat);
+
+            if (index == kMaxIndicesToCheck) {
+                ALOGW("[%s] stopping checking formats after %u: %s(%x)",
+                        name.c_str(), index,
+                        asString(portFormat.eColorFormat), portFormat.eColorFormat);
+            }
         }
     }
 
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 34d85e7..0fb5072 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -767,7 +767,7 @@
         return UNKNOWN_ERROR;
     }
 
-    return mCurrentInfo->setCapabilities(caps);
+    return mCurrentInfo->initializeCapabilities(caps);
 }
 
 status_t MediaCodecList::addQuirk(const char **attrs) {
diff --git a/media/libstagefright/SimpleDecodingSource.cpp b/media/libstagefright/SimpleDecodingSource.cpp
index e722ca6..407ac77 100644
--- a/media/libstagefright/SimpleDecodingSource.cpp
+++ b/media/libstagefright/SimpleDecodingSource.cpp
@@ -31,6 +31,7 @@
 using namespace android;
 
 const int64_t kTimeoutWaitForOutputUs = 500000; // 0.5 seconds
+const int64_t kTimeoutWaitForInputUs = 5000; // 5 milliseconds
 
 //static
 sp<SimpleDecodingSource> SimpleDecodingSource::Create(
@@ -205,13 +206,14 @@
         return ERROR_END_OF_STREAM;
     }
 
-    for (int retries = 1; ++retries; ) {
+    for (int retries = 0; ++retries; ) {
         // If we fill all available input buffers, we should expect that
         // the codec produces at least one output buffer. Also, the codec
         // should produce an output buffer in at most 1 seconds. Retry a
         // few times nonetheless.
         while (!me->mQueuedInputEOS) {
-            res = mCodec->dequeueInputBuffer(&in_ix, 0);
+            // allow some time to get input buffer after flush
+            res = mCodec->dequeueInputBuffer(&in_ix, kTimeoutWaitForInputUs);
             if (res == -EAGAIN) {
                 // no available input buffers
                 break;