Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9067e30b authored by Andreas Huber's avatar Andreas Huber
Browse files

Parse the individual segment's duration as a floating point number which is now

allowed in later HLS specs.

Change-Id: I7c8296acb4e9b0f80022f3057769de0eea9ee0c6
related-to-bug: 4779022
parent 551e9560
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -296,6 +296,8 @@ sp<M3UParser> LiveSession::fetchPlaylist(const char *url) {
        new M3UParser(url, buffer->data(), buffer->size());

    if (playlist->initCheck() != OK) {
        LOGE("failed to parse .m3u8 playlist");

        return NULL;
    }

+41 −3
Original line number Diff line number Diff line
@@ -179,7 +179,7 @@ status_t M3UParser::parse(const void *_data, size_t size) {
                if (mIsVariantPlaylist) {
                    return ERROR_MALFORMED;
                }
                err = parseMetaData(line, &itemMeta, "duration");
                err = parseMetaDataDuration(line, &itemMeta, "durationUs");
            } else if (line.startsWith("#EXT-X-DISCONTINUITY")) {
                if (mIsVariantPlaylist) {
                    return ERROR_MALFORMED;
@@ -203,9 +203,9 @@ status_t M3UParser::parse(const void *_data, size_t size) {

        if (!line.startsWith("#")) {
            if (!mIsVariantPlaylist) {
                int32_t durationSecs;
                int64_t durationUs;
                if (itemMeta == NULL
                        || !itemMeta->findInt32("duration", &durationSecs)) {
                        || !itemMeta->findInt64("durationUs", &durationUs)) {
                    return ERROR_MALFORMED;
                }
            }
@@ -251,6 +251,30 @@ status_t M3UParser::parseMetaData(
    return OK;
}

// static
status_t M3UParser::parseMetaDataDuration(
        const AString &line, sp<AMessage> *meta, const char *key) {
    ssize_t colonPos = line.find(":");

    if (colonPos < 0) {
        return ERROR_MALFORMED;
    }

    double x;
    status_t err = ParseDouble(line.c_str() + colonPos + 1, &x);

    if (err != OK) {
        return err;
    }

    if (meta->get() == NULL) {
        *meta = new AMessage;
    }
    (*meta)->setInt64(key, (int64_t)x * 1E6);

    return OK;
}

// static
status_t M3UParser::parseStreamInf(
        const AString &line, sp<AMessage> *meta) {
@@ -412,4 +436,18 @@ status_t M3UParser::ParseInt32(const char *s, int32_t *x) {
    return OK;
}

// static
status_t M3UParser::ParseDouble(const char *s, double *x) {
    char *end;
    double dval = strtod(s, &end);

    if (end == s || (*end != '\0' && *end != ',')) {
        return ERROR_MALFORMED;
    }

    *x = dval;

    return OK;
}

}  // namespace android
+4 −0
Original line number Diff line number Diff line
@@ -63,6 +63,9 @@ private:
    static status_t parseMetaData(
            const AString &line, sp<AMessage> *meta, const char *key);

    static status_t parseMetaDataDuration(
            const AString &line, sp<AMessage> *meta, const char *key);

    static status_t parseStreamInf(
            const AString &line, sp<AMessage> *meta);

@@ -70,6 +73,7 @@ private:
            const AString &line, sp<AMessage> *meta, const AString &baseURI);

    static status_t ParseInt32(const char *s, int32_t *x);
    static status_t ParseDouble(const char *s, double *x);

    DISALLOW_EVIL_CONSTRUCTORS(M3UParser);
};