From efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Wed, 25 Aug 2010 11:09:41 -0700 Subject: Allow sniffers to return a packet of opaque data that the corresponding extractor can take advantage of to not duplicate work already done sniffing. The mp3 extractor takes advantage of this now. Change-Id: Icb77ae3ee95a69c7da25b4d3b8696c0a2d33028a related-to-bug: 2948754 --- include/media/stagefright/DataSource.h | 9 ++++-- media/libstagefright/AMRExtractor.cpp | 5 ++-- media/libstagefright/DataSource.cpp | 17 ++++++++---- media/libstagefright/MP3Extractor.cpp | 32 ++++++++++++++++++---- media/libstagefright/MPEG4Extractor.cpp | 7 +++-- media/libstagefright/MediaExtractor.cpp | 7 +++-- media/libstagefright/OggExtractor.cpp | 3 +- media/libstagefright/WAVExtractor.cpp | 3 +- media/libstagefright/include/AMRExtractor.h | 4 ++- media/libstagefright/include/MP3Extractor.h | 6 ++-- media/libstagefright/include/MPEG2TSExtractor.h | 4 ++- media/libstagefright/include/MPEG4Extractor.h | 4 ++- media/libstagefright/include/OggExtractor.h | 4 ++- media/libstagefright/include/WAVExtractor.h | 4 ++- .../libstagefright/matroska/MatroskaExtractor.cpp | 3 +- media/libstagefright/matroska/MatroskaExtractor.h | 4 ++- media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp | 3 +- 17 files changed, 87 insertions(+), 32 deletions(-) diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h index 6f7dc38..9d2cff6 100644 --- a/include/media/stagefright/DataSource.h +++ b/include/media/stagefright/DataSource.h @@ -28,6 +28,7 @@ namespace android { +struct AMessage; class String8; class DataSource : public RefBase { @@ -59,10 +60,14 @@ public: //////////////////////////////////////////////////////////////////////////// - bool sniff(String8 *mimeType, float *confidence); + bool sniff(String8 *mimeType, float *confidence, sp *meta); + // The sniffer can optionally fill in "meta" with an AMessage containing + // a dictionary of values that helps the corresponding extractor initialize + // its state without duplicating effort already exerted by the sniffer. typedef bool (*SnifferFunc)( - const sp &source, String8 *mimeType, float *confidence); + const sp &source, String8 *mimeType, + float *confidence, sp *meta); static void RegisterSniffer(SnifferFunc func); static void RegisterDefaultSniffers(); diff --git a/media/libstagefright/AMRExtractor.cpp b/media/libstagefright/AMRExtractor.cpp index 70af2da..1b05528 100644 --- a/media/libstagefright/AMRExtractor.cpp +++ b/media/libstagefright/AMRExtractor.cpp @@ -87,7 +87,7 @@ AMRExtractor::AMRExtractor(const sp &source) mInitCheck(NO_INIT) { String8 mimeType; float confidence; - if (!SniffAMR(mDataSource, &mimeType, &confidence)) { + if (!SniffAMR(mDataSource, &mimeType, &confidence, NULL)) { return; } @@ -276,7 +276,8 @@ status_t AMRSource::read( //////////////////////////////////////////////////////////////////////////////// bool SniffAMR( - const sp &source, String8 *mimeType, float *confidence) { + const sp &source, String8 *mimeType, float *confidence, + sp *) { char header[9]; if (source->readAt(0, header, sizeof(header)) != sizeof(header)) { diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp index 90a596c..49eac62 100644 --- a/media/libstagefright/DataSource.cpp +++ b/media/libstagefright/DataSource.cpp @@ -25,6 +25,7 @@ #include "matroska/MatroskaExtractor.h" +#include #include #include #include @@ -56,19 +57,23 @@ status_t DataSource::getSize(off_t *size) { Mutex DataSource::gSnifferMutex; List DataSource::gSniffers; -bool DataSource::sniff(String8 *mimeType, float *confidence) { +bool DataSource::sniff( + String8 *mimeType, float *confidence, sp *meta) { *mimeType = ""; *confidence = 0.0f; + meta->clear(); Mutex::Autolock autoLock(gSnifferMutex); for (List::iterator it = gSniffers.begin(); it != gSniffers.end(); ++it) { String8 newMimeType; float newConfidence; - if ((*it)(this, &newMimeType, &newConfidence)) { + sp newMeta; + if ((*it)(this, &newMimeType, &newConfidence, &newMeta)) { if (newConfidence > *confidence) { *mimeType = newMimeType; *confidence = newConfidence; + *meta = newMeta; } } } @@ -92,13 +97,13 @@ void DataSource::RegisterSniffer(SnifferFunc func) { // static void DataSource::RegisterDefaultSniffers() { - RegisterSniffer(SniffMP3); RegisterSniffer(SniffMPEG4); - RegisterSniffer(SniffAMR); - RegisterSniffer(SniffWAV); - RegisterSniffer(SniffOgg); RegisterSniffer(SniffMatroska); + RegisterSniffer(SniffOgg); + RegisterSniffer(SniffWAV); + RegisterSniffer(SniffAMR); RegisterSniffer(SniffMPEG2TS); + RegisterSniffer(SniffMP3); } // static diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp index 4058fbc..2e36968 100644 --- a/media/libstagefright/MP3Extractor.cpp +++ b/media/libstagefright/MP3Extractor.cpp @@ -22,6 +22,7 @@ #include "include/ID3.h" +#include #include #include #include @@ -456,15 +457,31 @@ private: MP3Source &operator=(const MP3Source &); }; -MP3Extractor::MP3Extractor(const sp &source) +MP3Extractor::MP3Extractor( + const sp &source, const sp &meta) : mDataSource(source), mFirstFramePos(-1), mFixedHeader(0), mByteNumber(0) { off_t pos = 0; uint32_t header; - bool success = Resync(mDataSource, 0, &pos, &header); - CHECK(success); + bool success; + + int64_t meta_offset; + uint32_t meta_header; + if (meta != NULL + && meta->findInt64("offset", &meta_offset) + && meta->findInt32("header", (int32_t *)&meta_header)) { + // The sniffer has already done all the hard work for us, simply + // accept its judgement. + pos = (off_t)meta_offset; + header = meta_header; + + success = true; + } else { + success = Resync(mDataSource, 0, &pos, &header); + CHECK(success); + } if (success) { mFirstFramePos = pos; @@ -759,15 +776,20 @@ sp MP3Extractor::getMetaData() { } bool SniffMP3( - const sp &source, String8 *mimeType, float *confidence) { + const sp &source, String8 *mimeType, + float *confidence, sp *meta) { off_t pos = 0; uint32_t header; if (!Resync(source, 0, &pos, &header)) { return false; } + *meta = new AMessage; + (*meta)->setInt64("offset", pos); + (*meta)->setInt32("header", header); + *mimeType = MEDIA_MIMETYPE_AUDIO_MPEG; - *confidence = 0.3f; + *confidence = 0.2f; return true; } diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index 12a1e6e..ba90407 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -1738,7 +1738,7 @@ static bool LegacySniffMPEG4( || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; - *confidence = 0.1; + *confidence = 0.4; return true; } @@ -1805,13 +1805,14 @@ static bool BetterSniffMPEG4( } *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; - *confidence = 0.3f; + *confidence = 0.4f; return true; } bool SniffMPEG4( - const sp &source, String8 *mimeType, float *confidence) { + const sp &source, String8 *mimeType, float *confidence, + sp *) { if (BetterSniffMPEG4(source, mimeType, confidence)) { return true; } diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp index 56e6136..9bc94de 100644 --- a/media/libstagefright/MediaExtractor.cpp +++ b/media/libstagefright/MediaExtractor.cpp @@ -27,6 +27,7 @@ #include "matroska/MatroskaExtractor.h" +#include #include #include #include @@ -46,10 +47,12 @@ uint32_t MediaExtractor::flags() const { // static sp MediaExtractor::Create( const sp &source, const char *mime) { + sp meta; + String8 tmp; if (mime == NULL) { float confidence; - if (!source->sniff(&tmp, &confidence)) { + if (!source->sniff(&tmp, &confidence, &meta)) { LOGV("FAILED to autodetect media content."); return NULL; @@ -64,7 +67,7 @@ sp MediaExtractor::Create( || !strcasecmp(mime, "audio/mp4")) { return new MPEG4Extractor(source); } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { - return new MP3Extractor(source); + return new MP3Extractor(source, meta); } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB) || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { return new AMRExtractor(source); diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp index 9630092..2c1311a 100644 --- a/media/libstagefright/OggExtractor.cpp +++ b/media/libstagefright/OggExtractor.cpp @@ -804,7 +804,8 @@ sp OggExtractor::getMetaData() { } bool SniffOgg( - const sp &source, String8 *mimeType, float *confidence) { + const sp &source, String8 *mimeType, float *confidence, + sp *) { char tmp[4]; if (source->readAt(0, tmp, 4) < 4 || memcmp(tmp, "OggS", 4)) { return false; diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp index 8d820c0..57c1075 100644 --- a/media/libstagefright/WAVExtractor.cpp +++ b/media/libstagefright/WAVExtractor.cpp @@ -404,7 +404,8 @@ status_t WAVSource::read( //////////////////////////////////////////////////////////////////////////////// bool SniffWAV( - const sp &source, String8 *mimeType, float *confidence) { + const sp &source, String8 *mimeType, float *confidence, + sp *) { char header[12]; if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) { return false; diff --git a/media/libstagefright/include/AMRExtractor.h b/media/libstagefright/include/AMRExtractor.h index db49fe4..1cdf36d 100644 --- a/media/libstagefright/include/AMRExtractor.h +++ b/media/libstagefright/include/AMRExtractor.h @@ -22,6 +22,7 @@ namespace android { +struct AMessage; class String8; class AMRExtractor : public MediaExtractor { @@ -49,7 +50,8 @@ private: }; bool SniffAMR( - const sp &source, String8 *mimeType, float *confidence); + const sp &source, String8 *mimeType, float *confidence, + sp *); } // namespace android diff --git a/media/libstagefright/include/MP3Extractor.h b/media/libstagefright/include/MP3Extractor.h index 3ce6df3..0e6ccde 100644 --- a/media/libstagefright/include/MP3Extractor.h +++ b/media/libstagefright/include/MP3Extractor.h @@ -22,13 +22,14 @@ namespace android { +struct AMessage; class DataSource; class String8; class MP3Extractor : public MediaExtractor { public: // Extractor assumes ownership of "source". - MP3Extractor(const sp &source); + MP3Extractor(const sp &source, const sp &meta); virtual size_t countTracks(); virtual sp getTrack(size_t index); @@ -52,7 +53,8 @@ private: }; bool SniffMP3( - const sp &source, String8 *mimeType, float *confidence); + const sp &source, String8 *mimeType, float *confidence, + sp *meta); } // namespace android diff --git a/media/libstagefright/include/MPEG2TSExtractor.h b/media/libstagefright/include/MPEG2TSExtractor.h index c96973b..1bf4cd1 100644 --- a/media/libstagefright/include/MPEG2TSExtractor.h +++ b/media/libstagefright/include/MPEG2TSExtractor.h @@ -9,6 +9,7 @@ namespace android { +struct AMessage; struct AnotherPacketSource; struct ATSParser; struct DataSource; @@ -47,7 +48,8 @@ private: }; bool SniffMPEG2TS( - const sp &source, String8 *mimeType, float *confidence); + const sp &source, String8 *mimeType, float *confidence, + sp *); } // namespace android diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h index c8663d5..1c9cc7e 100644 --- a/media/libstagefright/include/MPEG4Extractor.h +++ b/media/libstagefright/include/MPEG4Extractor.h @@ -23,6 +23,7 @@ namespace android { +struct AMessage; class DataSource; class SampleTable; class String8; @@ -75,7 +76,8 @@ private: }; bool SniffMPEG4( - const sp &source, String8 *mimeType, float *confidence); + const sp &source, String8 *mimeType, float *confidence, + sp *); } // namespace android diff --git a/media/libstagefright/include/OggExtractor.h b/media/libstagefright/include/OggExtractor.h index 7066669..1eda025 100644 --- a/media/libstagefright/include/OggExtractor.h +++ b/media/libstagefright/include/OggExtractor.h @@ -22,6 +22,7 @@ namespace android { +struct AMessage; class DataSource; class String8; @@ -53,7 +54,8 @@ private: }; bool SniffOgg( - const sp &source, String8 *mimeType, float *confidence); + const sp &source, String8 *mimeType, float *confidence, + sp *); } // namespace android diff --git a/media/libstagefright/include/WAVExtractor.h b/media/libstagefright/include/WAVExtractor.h index 3e847b9..df6d3e7 100644 --- a/media/libstagefright/include/WAVExtractor.h +++ b/media/libstagefright/include/WAVExtractor.h @@ -22,6 +22,7 @@ namespace android { +struct AMessage; class DataSource; class String8; @@ -58,7 +59,8 @@ private: }; bool SniffWAV( - const sp &source, String8 *mimeType, float *confidence); + const sp &source, String8 *mimeType, float *confidence, + sp *); } // namespace android diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp index 71f6587..7c7d69e 100644 --- a/media/libstagefright/matroska/MatroskaExtractor.cpp +++ b/media/libstagefright/matroska/MatroskaExtractor.cpp @@ -579,7 +579,8 @@ sp MatroskaExtractor::getMetaData() { } bool SniffMatroska( - const sp &source, String8 *mimeType, float *confidence) { + const sp &source, String8 *mimeType, float *confidence, + sp *) { DataSourceReader reader(source); mkvparser::EBMLHeader ebmlHeader; long long pos; diff --git a/media/libstagefright/matroska/MatroskaExtractor.h b/media/libstagefright/matroska/MatroskaExtractor.h index 7471848..fa20b84 100644 --- a/media/libstagefright/matroska/MatroskaExtractor.h +++ b/media/libstagefright/matroska/MatroskaExtractor.h @@ -27,6 +27,7 @@ struct Segment; namespace android { +struct AMessage; class String8; struct DataSourceReader; @@ -69,7 +70,8 @@ private: }; bool SniffMatroska( - const sp &source, String8 *mimeType, float *confidence); + const sp &source, String8 *mimeType, float *confidence, + sp *); } // namespace android diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp index b287c95..56ca375 100644 --- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp +++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp @@ -174,7 +174,8 @@ status_t MPEG2TSExtractor::feedMore() { //////////////////////////////////////////////////////////////////////////////// bool SniffMPEG2TS( - const sp &source, String8 *mimeType, float *confidence) { + const sp &source, String8 *mimeType, float *confidence, + sp *) { #if 0 char header; if (source->readAt(0, &header, 1) != 1 || header != 0x47) { -- cgit v1.1