summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/DataSource.cpp
diff options
context:
space:
mode:
authorChong Zhang <chz@google.com>2014-08-05 20:54:44 -0700
committerChong Zhang <chz@google.com>2014-08-06 15:23:54 -0700
commit3de157dd8f9cd45bf9b0406268f5830887105ae1 (patch)
tree4c3423bb8c2005aac32ab3519ad73978d144b8ad /media/libstagefright/DataSource.cpp
parent92ce4715315bddd158c7d4028556632f0547e3b9 (diff)
downloadframeworks_av-3de157dd8f9cd45bf9b0406268f5830887105ae1.zip
frameworks_av-3de157dd8f9cd45bf9b0406268f5830887105ae1.tar.gz
frameworks_av-3de157dd8f9cd45bf9b0406268f5830887105ae1.tar.bz2
some fixes for crash when extractor creation fails
- prefetch data for sniffing - notify error instead of crashing if extractor is NULL Bug: 16818302 Change-Id: I56ff4996d99ac2811d19d141f7ff7acdd7c1da17
Diffstat (limited to 'media/libstagefright/DataSource.cpp')
-rw-r--r--media/libstagefright/DataSource.cpp80
1 files changed, 78 insertions, 2 deletions
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 6e0f37a..908cdca 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -13,6 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+//#define LOG_NDEBUG 0
+#define LOG_TAG "DataSource"
#include "include/AMRExtractor.h"
@@ -33,6 +35,7 @@
#include <media/IMediaHTTPConnection.h>
#include <media/IMediaHTTPService.h>
+#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/DataURISource.h>
@@ -182,7 +185,12 @@ void DataSource::RegisterDefaultSniffers() {
sp<DataSource> DataSource::CreateFromURI(
const sp<IMediaHTTPService> &httpService,
const char *uri,
- const KeyedVector<String8, String8> *headers) {
+ const KeyedVector<String8, String8> *headers,
+ AString *sniffedMIME) {
+ if (sniffedMIME != NULL) {
+ *sniffedMIME = "";
+ }
+
bool isWidevine = !strncasecmp("widevine://", uri, 11);
sp<DataSource> source;
@@ -202,6 +210,7 @@ sp<DataSource> DataSource::CreateFromURI(
}
if (httpSource->connect(uri, headers) != OK) {
+ ALOGE("Failed to connect http source!");
return NULL;
}
@@ -214,9 +223,76 @@ sp<DataSource> DataSource::CreateFromURI(
&copy, &cacheConfig, &disconnectAtHighwatermark);
}
- source = new NuCachedSource2(
+ sp<NuCachedSource2> cachedSource = new NuCachedSource2(
httpSource,
cacheConfig.isEmpty() ? NULL : cacheConfig.string());
+
+ String8 contentType = httpSource->getMIMEType();
+
+ if (strncasecmp(contentType.string(), "audio/", 6)) {
+ // We're not doing this for streams that appear to be audio-only
+ // streams to ensure that even low bandwidth streams start
+ // playing back fairly instantly.
+
+ // We're going to prefill the cache before trying to instantiate
+ // the extractor below, as the latter is an operation that otherwise
+ // could block on the datasource for a significant amount of time.
+ // During that time we'd be unable to abort the preparation phase
+ // without this prefill.
+
+ // Initially make sure we have at least 192 KB for the sniff
+ // to complete without blocking.
+ static const size_t kMinBytesForSniffing = 192 * 1024;
+
+ off64_t metaDataSize = -1ll;
+ for (;;) {
+ status_t finalStatus;
+ size_t cachedDataRemaining =
+ cachedSource->approxDataRemaining(&finalStatus);
+
+ if (finalStatus != OK || (metaDataSize >= 0
+ && (off64_t)cachedDataRemaining >= metaDataSize)) {
+ ALOGV("stop caching, status %d, "
+ "metaDataSize %lld, cachedDataRemaining %zu",
+ finalStatus, metaDataSize, cachedDataRemaining);
+ break;
+ }
+
+ ALOGV("now cached %zu bytes of data", cachedDataRemaining);
+
+ if (metaDataSize < 0
+ && cachedDataRemaining >= kMinBytesForSniffing) {
+ String8 tmp;
+ float confidence;
+ sp<AMessage> meta;
+ if (!cachedSource->sniff(&tmp, &confidence, &meta)) {
+ return NULL;
+ }
+
+ // We successfully identified the file's extractor to
+ // be, remember this mime type so we don't have to
+ // sniff it again when we call MediaExtractor::Create()
+ if (sniffedMIME != NULL) {
+ *sniffedMIME = tmp.string();
+ }
+
+ if (meta == NULL
+ || !meta->findInt64("meta-data-size",
+ reinterpret_cast<int64_t*>(&metaDataSize))) {
+ metaDataSize = kDefaultMetaSize;
+ }
+
+ if (metaDataSize < 0ll) {
+ ALOGE("invalid metaDataSize = %lld bytes", metaDataSize);
+ return NULL;
+ }
+ }
+
+ usleep(200000);
+ }
+ }
+
+ source = cachedSource;
} else {
// We do not want that prefetching, caching, datasource wrapper
// in the widevine:// case.