diff options
author | Andreas Huber <andih@google.com> | 2010-09-08 14:32:20 -0700 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2010-10-07 11:41:43 -0700 |
commit | 2a4d22d79e927f2245537921e10fc5fda1c47a29 (patch) | |
tree | 1452ec4c157a5f701d4aea84f2107477d5324d94 /media/libstagefright/httplive/M3UParser.cpp | |
parent | 2b82e9652ba049e754c2cc74e381282f231d5fbf (diff) | |
download | frameworks_av-2a4d22d79e927f2245537921e10fc5fda1c47a29.tar.gz frameworks_av-2a4d22d79e927f2245537921e10fc5fda1c47a29.tar.bz2 frameworks_av-2a4d22d79e927f2245537921e10fc5fda1c47a29.zip |
Work to support switching transport streams mid-stream and signalling discontinuities to the decoder.
Change-Id: I7150e5e7342e1117c524856b204aadcb763e06ed
related-to-bug: 2368598
Diffstat (limited to 'media/libstagefright/httplive/M3UParser.cpp')
-rw-r--r-- | media/libstagefright/httplive/M3UParser.cpp | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp index edd8648e07..0d7daa9cae 100644 --- a/media/libstagefright/httplive/M3UParser.cpp +++ b/media/libstagefright/httplive/M3UParser.cpp @@ -74,7 +74,8 @@ bool M3UParser::itemAt(size_t index, AString *uri, sp<AMessage> *meta) { static bool MakeURL(const char *baseURL, const char *url, AString *out) { out->clear(); - if (strncasecmp("http://", baseURL, 7)) { + if (strncasecmp("http://", baseURL, 7) + && strncasecmp("file://", baseURL, 7)) { // Base URL must be absolute return false; } @@ -128,7 +129,12 @@ status_t M3UParser::parse(const void *_data, size_t size) { line.setTo(&data[offset], offsetLF - offset); } - LOGI("#%s#", line.c_str()); + // LOGI("#%s#", line.c_str()); + + if (line.empty()) { + offset = offsetLF + 1; + continue; + } if (lineNo == 0 && line == "#EXTM3U") { mIsExtM3U = true; @@ -152,11 +158,20 @@ status_t M3UParser::parse(const void *_data, size_t size) { return ERROR_MALFORMED; } err = parseMetaData(line, &itemMeta, "duration"); + } else if (line.startsWith("#EXT-X-DISCONTINUITY")) { + if (mIsVariantPlaylist) { + return ERROR_MALFORMED; + } + if (itemMeta == NULL) { + itemMeta = new AMessage; + } + itemMeta->setInt32("discontinuity", true); } else if (line.startsWith("#EXT-X-STREAM-INF")) { if (mMeta != NULL) { return ERROR_MALFORMED; } mIsVariantPlaylist = true; + err = parseStreamInf(line, &itemMeta); } if (err != OK) { @@ -215,6 +230,61 @@ status_t M3UParser::parseMetaData( } // static +status_t M3UParser::parseStreamInf( + const AString &line, sp<AMessage> *meta) { + ssize_t colonPos = line.find(":"); + + if (colonPos < 0) { + return ERROR_MALFORMED; + } + + size_t offset = colonPos + 1; + + while (offset < line.size()) { + ssize_t end = line.find(",", offset); + if (end < 0) { + end = line.size(); + } + + AString attr(line, offset, end - offset); + attr.trim(); + + offset = end + 1; + + ssize_t equalPos = attr.find("="); + if (equalPos < 0) { + continue; + } + + AString key(attr, 0, equalPos); + key.trim(); + + AString val(attr, equalPos + 1, attr.size() - equalPos - 1); + val.trim(); + + LOGV("key=%s value=%s", key.c_str(), val.c_str()); + + if (!strcasecmp("bandwidth", key.c_str())) { + const char *s = val.c_str(); + char *end; + unsigned long x = strtoul(s, &end, 10); + + if (end == s || *end != '\0') { + // malformed + continue; + } + + if (meta->get() == NULL) { + *meta = new AMessage; + } + (*meta)->setInt32("bandwidth", x); + } + } + + return OK; +} + +// static status_t M3UParser::ParseInt32(const char *s, int32_t *x) { char *end; long lval = strtol(s, &end, 10); |