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

Commit 261eb0cb authored by Andreas Huber's avatar Andreas Huber
Browse files

Better sniffing of MPEG4 content by checking for a compatible sub-brand.

Change-Id: I076908822ad0e663b9932e61fb33edc12c2e1948
related-to-bug: 2673192
parent 2cb138db
Loading
Loading
Loading
Loading
+79 −1
Original line number Diff line number Diff line
@@ -1633,7 +1633,7 @@ status_t MPEG4Source::read(
    }
}

bool SniffMPEG4(
static bool LegacySniffMPEG4(
        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
    uint8_t header[8];

@@ -1657,5 +1657,83 @@ bool SniffMPEG4(
    return false;
}

static bool isCompatibleBrand(uint32_t fourcc) {
    static const uint32_t kCompatibleBrands[] = {
        FOURCC('i', 's', 'o', 'm'),
        FOURCC('i', 's', 'o', '2'),
        FOURCC('a', 'v', 'c', '1'),
        FOURCC('3', 'g', 'p', '4'),
        FOURCC('m', 'p', '4', '1'),
        FOURCC('m', 'p', '4', '2'),
    };

    for (size_t i = 0;
         i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]);
         ++i) {
        if (kCompatibleBrands[i] == fourcc) {
            return true;
        }
    }

    return false;
}

// Attempt to actually parse the 'ftyp' atom and determine if a suitable
// compatible brand is present.
static bool BetterSniffMPEG4(
        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
    uint8_t header[12];
    if (source->readAt(0, header, 12) != 12
            || memcmp("ftyp", &header[4], 4)) {
        return false;
    }

    size_t atomSize = U32_AT(&header[0]);
    if (atomSize < 16 || (atomSize % 4) != 0) {
        return false;
    }

    bool success = false;
    if (isCompatibleBrand(U32_AT(&header[8]))) {
        success = true;
    } else {
        size_t numCompatibleBrands = (atomSize - 16) / 4;
        for (size_t i = 0; i < numCompatibleBrands; ++i) {
            uint8_t tmp[4];
            if (source->readAt(16 + i * 4, tmp, 4) != 4) {
                return false;
            }

            if (isCompatibleBrand(U32_AT(&tmp[0]))) {
                success = true;
                break;
            }
        }
    }

    if (!success) {
        return false;
    }

    *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
    *confidence = 0.3f;

    return true;
}

bool SniffMPEG4(
        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
    if (BetterSniffMPEG4(source, mimeType, confidence)) {
        return true;
    }

    if (LegacySniffMPEG4(source, mimeType, confidence)) {
        LOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
        return true;
    }

    return false;
}

}  // namespace android