diff options
Diffstat (limited to 'media/libstagefright/DataSource.cpp')
-rw-r--r-- | media/libstagefright/DataSource.cpp | 150 |
1 files changed, 110 insertions, 40 deletions
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp index 85d0292..2df045f 100644 --- a/media/libstagefright/DataSource.cpp +++ b/media/libstagefright/DataSource.cpp @@ -47,11 +47,28 @@ #include <utils/String8.h> #include <cutils/properties.h> +#include <cutils/log.h> + +#include <dlfcn.h> #include <stagefright/AVExtensions.h> namespace android { +static void *loadExtractorPlugin() { + void *ret = NULL; + char lib[PROPERTY_VALUE_MAX]; + if (property_get("media.sf.extractor-plugin", lib, NULL)) { + if (void *extractorLib = ::dlopen(lib, RTLD_LAZY)) { + ret = ::dlsym(extractorLib, "getExtractorPlugin"); + ALOGW_IF(!ret, "Failed to find symbol, dlerror: %s", ::dlerror()); + } else { + ALOGV("Failed to load %s, dlerror: %s", lib, ::dlerror()); + } + } + return ret; +} + bool DataSource::getUInt16(off64_t offset, uint16_t *x) { *x = 0; @@ -112,29 +129,49 @@ status_t DataSource::getSize(off64_t *size) { //////////////////////////////////////////////////////////////////////////////// -Mutex DataSource::gSnifferMutex; -List<DataSource::SnifferFunc> DataSource::gSniffers; -bool DataSource::gSniffersRegistered = false; - bool DataSource::sniff( String8 *mimeType, float *confidence, sp<AMessage> *meta) { + + return mSniffer->sniff(this, mimeType, confidence, meta); +} + +// static +void DataSource::RegisterSniffer_l(SnifferFunc /* func */) { + return; +} + +// static +void DataSource::RegisterDefaultSniffers() { + return; +} + +//////////////////////////////////////////////////////////////////////////////// + +Sniffer::Sniffer() { + registerDefaultSniffers(); +} + +bool Sniffer::sniff( + DataSource *source, String8 *mimeType, float *confidence, sp<AMessage> *meta) { + + bool forceExtraSniffers = false; + + if (*confidence == 3.14f) { + // Magic value, as set by MediaExtractor when a video container looks incomplete + forceExtraSniffers = true; + } + *mimeType = ""; *confidence = 0.0f; meta->clear(); - { - Mutex::Autolock autoLock(gSnifferMutex); - if (!gSniffersRegistered) { - return false; - } - } - - for (List<SnifferFunc>::iterator it = gSniffers.begin(); - it != gSniffers.end(); ++it) { + Mutex::Autolock autoLock(mSnifferMutex); + for (List<SnifferFunc>::iterator it = mSniffers.begin(); + it != mSniffers.end(); ++it) { String8 newMimeType; float newConfidence; sp<AMessage> newMeta; - if ((*it)(this, &newMimeType, &newConfidence, &newMeta)) { + if ((*it)(source, &newMimeType, &newConfidence, &newMeta)) { if (newConfidence > *confidence) { *mimeType = newMimeType; *confidence = newConfidence; @@ -143,48 +180,81 @@ bool DataSource::sniff( } } + /* Only do the deeper sniffers if the results are null or in doubt */ + if (mimeType->length() == 0 || *confidence < 0.21f || forceExtraSniffers) { + for (List<SnifferFunc>::iterator it = mExtraSniffers.begin(); + it != mExtraSniffers.end(); ++it) { + String8 newMimeType; + float newConfidence; + sp<AMessage> newMeta; + if ((*it)(source, &newMimeType, &newConfidence, &newMeta)) { + if (newConfidence > *confidence) { + *mimeType = newMimeType; + *confidence = newConfidence; + *meta = newMeta; + } + } + } + } + return *confidence > 0.0; } -// static -void DataSource::RegisterSniffer_l(SnifferFunc func) { - for (List<SnifferFunc>::iterator it = gSniffers.begin(); - it != gSniffers.end(); ++it) { +void Sniffer::registerSniffer_l(SnifferFunc func) { + + for (List<SnifferFunc>::iterator it = mSniffers.begin(); + it != mSniffers.end(); ++it) { if (*it == func) { return; } } - gSniffers.push_back(func); + mSniffers.push_back(func); } -// static -void DataSource::RegisterDefaultSniffers() { - Mutex::Autolock autoLock(gSnifferMutex); - if (gSniffersRegistered) { - return; +void Sniffer::registerSnifferPlugin() { + static void (*getExtractorPlugin)(MediaExtractor::Plugin *) = + (void (*)(MediaExtractor::Plugin *))loadExtractorPlugin(); + + MediaExtractor::Plugin *plugin = MediaExtractor::getPlugin(); + if (!plugin->sniff && getExtractorPlugin) { + getExtractorPlugin(plugin); } + if (plugin->sniff) { + for (List<SnifferFunc>::iterator it = mExtraSniffers.begin(); + it != mExtraSniffers.end(); ++it) { + if (*it == plugin->sniff) { + return; + } + } + + mExtraSniffers.push_back(plugin->sniff); + } +} - RegisterSniffer_l(SniffMPEG4); - RegisterSniffer_l(SniffMatroska); - RegisterSniffer_l(SniffOgg); - RegisterSniffer_l(SniffWAV); - RegisterSniffer_l(SniffFLAC); - RegisterSniffer_l(SniffAMR); - RegisterSniffer_l(SniffMPEG2TS); - RegisterSniffer_l(SniffMP3); - RegisterSniffer_l(SniffAAC); - RegisterSniffer_l(SniffMPEG2PS); - RegisterSniffer_l(SniffWVM); - RegisterSniffer_l(SniffMidi); - RegisterSniffer_l(AVUtils::get()->getExtendedSniffer()); +void Sniffer::registerDefaultSniffers() { + Mutex::Autolock autoLock(mSnifferMutex); + + registerSniffer_l(SniffMPEG4); + registerSniffer_l(SniffMatroska); + registerSniffer_l(SniffOgg); + registerSniffer_l(SniffWAV); + registerSniffer_l(SniffFLAC); + registerSniffer_l(SniffAMR); + registerSniffer_l(SniffMPEG2TS); + registerSniffer_l(SniffMP3); + registerSniffer_l(SniffAAC); + registerSniffer_l(SniffMPEG2PS); + registerSniffer_l(SniffWVM); + registerSniffer_l(SniffMidi); + registerSniffer_l(AVUtils::get()->getExtendedSniffer()); + registerSnifferPlugin(); char value[PROPERTY_VALUE_MAX]; if (property_get("drm.service.enabled", value, NULL) && (!strcmp(value, "1") || !strcasecmp(value, "true"))) { - RegisterSniffer_l(SniffDRM); + registerSniffer_l(SniffDRM); } - gSniffersRegistered = true; } // static @@ -256,7 +326,7 @@ sp<DataSource> DataSource::CreateFromURI( cacheConfig.isEmpty() ? NULL : cacheConfig.string(), disconnectAtHighwatermark); } else { - source = new NuCachedSource2( + source = NuCachedSource2::Create( httpSource, cacheConfig.isEmpty() ? NULL : cacheConfig.string(), disconnectAtHighwatermark); |