summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/DataSource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/DataSource.cpp')
-rw-r--r--media/libstagefright/DataSource.cpp150
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);