Distinguish QCELP audio from mpeg4 audio, ignore QCELP audio tracks since we don't have a decoder for it, ignore potentially malformed metadata for AMR NB and WB tracks.

Change-Id: Ic9a9198413431db4ea40bb63b9de91aa8a7183af
related-to-bug: 2587341
diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h
index 1efeb92..3f8bc51 100644
--- a/include/media/stagefright/MediaDefs.h
+++ b/include/media/stagefright/MediaDefs.h
@@ -31,6 +31,7 @@
 extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB;
 extern const char *MEDIA_MIMETYPE_AUDIO_MPEG;
 extern const char *MEDIA_MIMETYPE_AUDIO_AAC;
+extern const char *MEDIA_MIMETYPE_AUDIO_QCELP;
 extern const char *MEDIA_MIMETYPE_AUDIO_RAW;
 
 extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index c1987dc..2bc8139 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -763,9 +763,14 @@
                 mDurationUs = durationUs;
             }
         }
-    }
 
-    mAudioSource->start();
+        mAudioSource->start();
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) {
+        // For legacy reasons we're simply going to ignore the absence
+        // of an audio decoder for QCELP instead of aborting playback
+        // altogether.
+        return OK;
+    }
 
     return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
 }
diff --git a/media/libstagefright/ESDS.cpp b/media/libstagefright/ESDS.cpp
index 28d338c..b7c8e0c 100644
--- a/media/libstagefright/ESDS.cpp
+++ b/media/libstagefright/ESDS.cpp
@@ -25,7 +25,8 @@
       mSize(size),
       mInitCheck(NO_INIT),
       mDecoderSpecificOffset(0),
-      mDecoderSpecificLength(0) {
+      mDecoderSpecificLength(0),
+      mObjectTypeIndication(0) {
     memcpy(mData, data, size);
 
     mInitCheck = parse();
@@ -40,6 +41,16 @@
     return mInitCheck;
 }
 
+status_t ESDS::getObjectTypeIndication(uint8_t *objectTypeIndication) const {
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    *objectTypeIndication = mObjectTypeIndication;
+
+    return OK;
+}
+
 status_t ESDS::getCodecSpecificInfo(const void **data, size_t *size) const {
     if (mInitCheck != OK) {
         return mInitCheck;
@@ -164,6 +175,8 @@
         return ERROR_MALFORMED;
     }
 
+    mObjectTypeIndication = mData[offset];
+
     offset += 13;
     size -= 13;
 
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index bd3925a..0e21d08 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -741,19 +741,25 @@
             uint16_t data_ref_index = U16_AT(&buffer[6]);
             uint16_t num_channels = U16_AT(&buffer[16]);
 
-            if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB,
-                            FourCC2MIME(chunk_type))
-                || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB,
-                               FourCC2MIME(chunk_type))) {
-                // AMR audio is always mono.
-                num_channels = 1;
-            }
-
             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);
+            if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB,
+                            FourCC2MIME(chunk_type))) {
+                // AMR NB audio is always mono, 8kHz
+                num_channels = 1;
+                sample_rate = 8000;
+            } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB,
+                               FourCC2MIME(chunk_type))) {
+                // AMR WB audio is always mono, 16kHz
+                num_channels = 1;
+                sample_rate = 16000;
+            }
+
+#if 0
+            printf("*** coding='%s' %d channels, size %d, rate %d\n",
+                   chunk, num_channels, sample_size, sample_rate);
+#endif
 
             mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
             mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
@@ -1235,6 +1241,18 @@
 status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
         const void *esds_data, size_t esds_size) {
     ESDS esds(esds_data, esds_size);
+
+    uint8_t objectTypeIndication;
+    if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
+        return ERROR_MALFORMED;
+    }
+
+    if (objectTypeIndication == 0xe1) {
+        // This isn't MPEG4 audio at all, it's QCELP 14k...
+        mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
+        return OK;
+    }
+
     const uint8_t *csd;
     size_t csd_size;
     if (esds.getCodecSpecificInfo(
diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
index 04b1454..3a89170 100644
--- a/media/libstagefright/MediaDefs.cpp
+++ b/media/libstagefright/MediaDefs.cpp
@@ -29,6 +29,7 @@
 const char *MEDIA_MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb";
 const char *MEDIA_MIMETYPE_AUDIO_MPEG = "audio/mpeg";
 const char *MEDIA_MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
+const char *MEDIA_MIMETYPE_AUDIO_QCELP = "audio/qcelp";
 const char *MEDIA_MIMETYPE_AUDIO_RAW = "audio/raw";
 
 const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mpeg4";
diff --git a/media/libstagefright/include/ESDS.h b/media/libstagefright/include/ESDS.h
index 01bcd18..3a79951 100644
--- a/media/libstagefright/include/ESDS.h
+++ b/media/libstagefright/include/ESDS.h
@@ -31,6 +31,7 @@
 
     status_t InitCheck() const;
 
+    status_t getObjectTypeIndication(uint8_t *objectTypeIndication) const;
     status_t getCodecSpecificInfo(const void **data, size_t *size) const;
 
 private:
@@ -47,6 +48,7 @@
 
     size_t mDecoderSpecificOffset;
     size_t mDecoderSpecificLength;
+    uint8_t mObjectTypeIndication;
 
     status_t skipDescriptorHeader(
             size_t offset, size_t size,