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
This commit is contained in:
Andreas Huber
2010-08-25 11:09:41 -07:00
parent 231a000565
commit efdd088a71
17 changed files with 87 additions and 32 deletions

View File

@@ -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<AMessage> *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<DataSource> &source, String8 *mimeType, float *confidence);
const sp<DataSource> &source, String8 *mimeType,
float *confidence, sp<AMessage> *meta);
static void RegisterSniffer(SnifferFunc func);
static void RegisterDefaultSniffers();

View File

@@ -87,7 +87,7 @@ AMRExtractor::AMRExtractor(const sp<DataSource> &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<DataSource> &source, String8 *mimeType, float *confidence) {
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
char header[9];
if (source->readAt(0, header, sizeof(header)) != sizeof(header)) {

View File

@@ -25,6 +25,7 @@
#include "matroska/MatroskaExtractor.h"
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/FileSource.h>
#include <media/stagefright/MediaErrors.h>
@@ -56,19 +57,23 @@ status_t DataSource::getSize(off_t *size) {
Mutex DataSource::gSnifferMutex;
List<DataSource::SnifferFunc> DataSource::gSniffers;
bool DataSource::sniff(String8 *mimeType, float *confidence) {
bool DataSource::sniff(
String8 *mimeType, float *confidence, sp<AMessage> *meta) {
*mimeType = "";
*confidence = 0.0f;
meta->clear();
Mutex::Autolock autoLock(gSnifferMutex);
for (List<SnifferFunc>::iterator it = gSniffers.begin();
it != gSniffers.end(); ++it) {
String8 newMimeType;
float newConfidence;
if ((*it)(this, &newMimeType, &newConfidence)) {
sp<AMessage> 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

View File

@@ -22,6 +22,7 @@
#include "include/ID3.h"
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaBufferGroup.h>
@@ -456,15 +457,31 @@ private:
MP3Source &operator=(const MP3Source &);
};
MP3Extractor::MP3Extractor(const sp<DataSource> &source)
MP3Extractor::MP3Extractor(
const sp<DataSource> &source, const sp<AMessage> &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<MetaData> MP3Extractor::getMetaData() {
}
bool SniffMP3(
const sp<DataSource> &source, String8 *mimeType, float *confidence) {
const sp<DataSource> &source, String8 *mimeType,
float *confidence, sp<AMessage> *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;
}

View File

@@ -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<DataSource> &source, String8 *mimeType, float *confidence) {
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
if (BetterSniffMPEG4(source, mimeType, confidence)) {
return true;
}

View File

@@ -27,6 +27,7 @@
#include "matroska/MatroskaExtractor.h"
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaExtractor.h>
@@ -46,10 +47,12 @@ uint32_t MediaExtractor::flags() const {
// static
sp<MediaExtractor> MediaExtractor::Create(
const sp<DataSource> &source, const char *mime) {
sp<AMessage> 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> 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);

View File

@@ -804,7 +804,8 @@ sp<MetaData> OggExtractor::getMetaData() {
}
bool SniffOgg(
const sp<DataSource> &source, String8 *mimeType, float *confidence) {
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
char tmp[4];
if (source->readAt(0, tmp, 4) < 4 || memcmp(tmp, "OggS", 4)) {
return false;

View File

@@ -404,7 +404,8 @@ status_t WAVSource::read(
////////////////////////////////////////////////////////////////////////////////
bool SniffWAV(
const sp<DataSource> &source, String8 *mimeType, float *confidence) {
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
char header[12];
if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
return false;

View File

@@ -22,6 +22,7 @@
namespace android {
struct AMessage;
class String8;
class AMRExtractor : public MediaExtractor {
@@ -49,7 +50,8 @@ private:
};
bool SniffAMR(
const sp<DataSource> &source, String8 *mimeType, float *confidence);
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *);
} // namespace android

View File

@@ -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<DataSource> &source);
MP3Extractor(const sp<DataSource> &source, const sp<AMessage> &meta);
virtual size_t countTracks();
virtual sp<MediaSource> getTrack(size_t index);
@@ -52,7 +53,8 @@ private:
};
bool SniffMP3(
const sp<DataSource> &source, String8 *mimeType, float *confidence);
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *meta);
} // namespace android

View File

@@ -9,6 +9,7 @@
namespace android {
struct AMessage;
struct AnotherPacketSource;
struct ATSParser;
struct DataSource;
@@ -47,7 +48,8 @@ private:
};
bool SniffMPEG2TS(
const sp<DataSource> &source, String8 *mimeType, float *confidence);
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *);
} // namespace android

View File

@@ -23,6 +23,7 @@
namespace android {
struct AMessage;
class DataSource;
class SampleTable;
class String8;
@@ -75,7 +76,8 @@ private:
};
bool SniffMPEG4(
const sp<DataSource> &source, String8 *mimeType, float *confidence);
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *);
} // namespace android

View File

@@ -22,6 +22,7 @@
namespace android {
struct AMessage;
class DataSource;
class String8;
@@ -53,7 +54,8 @@ private:
};
bool SniffOgg(
const sp<DataSource> &source, String8 *mimeType, float *confidence);
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *);
} // namespace android

View File

@@ -22,6 +22,7 @@
namespace android {
struct AMessage;
class DataSource;
class String8;
@@ -58,7 +59,8 @@ private:
};
bool SniffWAV(
const sp<DataSource> &source, String8 *mimeType, float *confidence);
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *);
} // namespace android

View File

@@ -579,7 +579,8 @@ sp<MetaData> MatroskaExtractor::getMetaData() {
}
bool SniffMatroska(
const sp<DataSource> &source, String8 *mimeType, float *confidence) {
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
DataSourceReader reader(source);
mkvparser::EBMLHeader ebmlHeader;
long long pos;

View File

@@ -27,6 +27,7 @@ struct Segment;
namespace android {
struct AMessage;
class String8;
struct DataSourceReader;
@@ -69,7 +70,8 @@ private:
};
bool SniffMatroska(
const sp<DataSource> &source, String8 *mimeType, float *confidence);
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *);
} // namespace android

View File

@@ -174,7 +174,8 @@ status_t MPEG2TSExtractor::feedMore() {
////////////////////////////////////////////////////////////////////////////////
bool SniffMPEG2TS(
const sp<DataSource> &source, String8 *mimeType, float *confidence) {
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
#if 0
char header;
if (source->readAt(0, &header, 1) != 1 || header != 0x47) {