summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/MPEG4Extractor.cpp
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-05-27 09:59:54 -0700
committerAndreas Huber <andih@google.com>2010-05-27 09:59:54 -0700
commit1b52bd2874aef6c9cbc141f1cff5205830515f7d (patch)
tree388828a3e0fe92a6d3652b8ecf86a2f9dddb5928 /media/libstagefright/MPEG4Extractor.cpp
parent8a74f1bc3f64943cafdc7c6c7e1900b4a3e9e4b1 (diff)
downloadframeworks_av-1b52bd2874aef6c9cbc141f1cff5205830515f7d.zip
frameworks_av-1b52bd2874aef6c9cbc141f1cff5205830515f7d.tar.gz
frameworks_av-1b52bd2874aef6c9cbc141f1cff5205830515f7d.tar.bz2
Better sniffing of MPEG4 content by checking for a compatible sub-brand.
Change-Id: I076908822ad0e663b9932e61fb33edc12c2e1948 related-to-bug: 2673192
Diffstat (limited to 'media/libstagefright/MPEG4Extractor.cpp')
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp80
1 files changed, 79 insertions, 1 deletions
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index a41b2f4..3639db4 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1633,7 +1633,7 @@ status_t MPEG4Source::read(
}
}
-bool SniffMPEG4(
+static bool LegacySniffMPEG4(
const sp<DataSource> &source, String8 *mimeType, float *confidence) {
uint8_t header[8];
@@ -1657,5 +1657,83 @@ bool SniffMPEG4(
return false;
}
+static bool isCompatibleBrand(uint32_t fourcc) {
+ static const uint32_t kCompatibleBrands[] = {
+ FOURCC('i', 's', 'o', 'm'),
+ FOURCC('i', 's', 'o', '2'),
+ FOURCC('a', 'v', 'c', '1'),
+ FOURCC('3', 'g', 'p', '4'),
+ FOURCC('m', 'p', '4', '1'),
+ FOURCC('m', 'p', '4', '2'),
+ };
+
+ for (size_t i = 0;
+ i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]);
+ ++i) {
+ if (kCompatibleBrands[i] == fourcc) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Attempt to actually parse the 'ftyp' atom and determine if a suitable
+// compatible brand is present.
+static bool BetterSniffMPEG4(
+ const sp<DataSource> &source, String8 *mimeType, float *confidence) {
+ uint8_t header[12];
+ if (source->readAt(0, header, 12) != 12
+ || memcmp("ftyp", &header[4], 4)) {
+ return false;
+ }
+
+ size_t atomSize = U32_AT(&header[0]);
+ if (atomSize < 16 || (atomSize % 4) != 0) {
+ return false;
+ }
+
+ bool success = false;
+ if (isCompatibleBrand(U32_AT(&header[8]))) {
+ success = true;
+ } else {
+ size_t numCompatibleBrands = (atomSize - 16) / 4;
+ for (size_t i = 0; i < numCompatibleBrands; ++i) {
+ uint8_t tmp[4];
+ if (source->readAt(16 + i * 4, tmp, 4) != 4) {
+ return false;
+ }
+
+ if (isCompatibleBrand(U32_AT(&tmp[0]))) {
+ success = true;
+ break;
+ }
+ }
+ }
+
+ if (!success) {
+ return false;
+ }
+
+ *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
+ *confidence = 0.3f;
+
+ return true;
+}
+
+bool SniffMPEG4(
+ const sp<DataSource> &source, String8 *mimeType, float *confidence) {
+ if (BetterSniffMPEG4(source, mimeType, confidence)) {
+ return true;
+ }
+
+ if (LegacySniffMPEG4(source, mimeType, confidence)) {
+ LOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
+ return true;
+ }
+
+ return false;
+}
+
} // namespace android