am b8814dce: Merge "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." into gingerbread

Merge commit 'b8814dce287552c1bdf13fa999296ebc7387776d' into gingerbread-plus-aosp

* commit 'b8814dce287552c1bdf13fa999296ebc7387776d':
  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.
This commit is contained in:
Andreas Huber
2010-08-25 13:13:57 -07:00
committed by Android Git Automerger
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) {