diff options
author | Andreas Huber <andih@google.com> | 2010-05-27 09:59:54 -0700 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2010-05-27 09:59:54 -0700 |
commit | 261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76 (patch) | |
tree | 5de44f64b48769e9cbca8a79527c61bfa90ea57a /media | |
parent | 2cb138dbe89c493547066679e1a8ef1ae0a848de (diff) | |
download | frameworks_base-261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76.zip frameworks_base-261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76.tar.gz frameworks_base-261eb0cbef1f3f7d3cde49d628b9c1e82dabcb76.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')
-rw-r--r-- | media/libstagefright/MPEG4Extractor.cpp | 80 |
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 |