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

Commit 63749954 authored by Andreas Huber's avatar Andreas Huber
Browse files

Support .avi tracks that have a sample size of 1, i.e. samples != chunks

Assume for now that all chunks are the same size, i.e. have the same number of
samples.

Change-Id: Ib8a7dfeb16cc3e5be199ff9d98b68dd0b9c23eb8
related-to-bug: 5279872
parent 62bb0cdc
Loading
Loading
Loading
Loading
+46 −13
Original line number Diff line number Diff line
@@ -117,14 +117,12 @@ status_t AVIExtractor::AVISource::read(
        }
    }

    int64_t timeUs =
        (mSampleIndex * 1000000ll * mTrack.mRate) / mTrack.mScale;

    off64_t offset;
    size_t size;
    bool isKey;
    int64_t timeUs;
    status_t err = mExtractor->getSampleInfo(
            mTrackIndex, mSampleIndex, &offset, &size, &isKey);
            mTrackIndex, mSampleIndex, &offset, &size, &isKey, &timeUs);

    ++mSampleIndex;

@@ -396,6 +394,8 @@ status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) {
    uint32_t rate = U32LE_AT(&data[20]);
    uint32_t scale = U32LE_AT(&data[24]);

    uint32_t sampleSize = U32LE_AT(&data[44]);

    const char *mime = NULL;
    Track::Kind kind = Track::OTHER;

@@ -427,6 +427,7 @@ status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) {
    track->mMeta = meta;
    track->mRate = rate;
    track->mScale = scale;
    track->mBytesPerSample = sampleSize;
    track->mKind = kind;
    track->mNumSyncSamples = 0;
    track->mThumbnailSampleSize = 0;
@@ -612,11 +613,12 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
        off64_t offset;
        size_t size;
        bool isKey;
        status_t err = getSampleInfo(0, 0, &offset, &size, &isKey);
        int64_t timeUs;
        status_t err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs);

        if (err != OK) {
            mOffsetsAreAbsolute = !mOffsetsAreAbsolute;
            err = getSampleInfo(0, 0, &offset, &size, &isKey);
            err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs);

            if (err != OK) {
                return err;
@@ -630,8 +632,9 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
    for (size_t i = 0; i < mTracks.size(); ++i) {
        Track *track = &mTracks.editItemAt(i);

        int64_t durationUs =
            (track->mSamples.size() * 1000000ll * track->mRate) / track->mScale;
        int64_t durationUs;
        CHECK_EQ((status_t)OK,
                 getSampleTime(i, track->mSamples.size() - 1, &durationUs));

        LOGV("track %d duration = %.2f secs", i, durationUs / 1E6);

@@ -645,9 +648,10 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {

        if (!strncasecmp("video/", mime.c_str(), 6)
                && track->mThumbnailSampleIndex >= 0) {
            int64_t thumbnailTimeUs =
                (track->mThumbnailSampleIndex * 1000000ll * track->mRate)
                    / track->mScale;
            int64_t thumbnailTimeUs;
            CHECK_EQ((status_t)OK,
                     getSampleTime(i, track->mThumbnailSampleIndex,
                                   &thumbnailTimeUs));

            track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);

@@ -659,6 +663,21 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
                }
            }
        }

        if (track->mBytesPerSample != 0) {
            // Assume all chunks are the same size for now.

            off64_t offset;
            size_t size;
            bool isKey;
            int64_t sampleTimeUs;
            CHECK_EQ((status_t)OK,
                     getSampleInfo(
                         i, 0,
                         &offset, &size, &isKey, &sampleTimeUs));

            track->mRate *= size / track->mBytesPerSample;
        }
    }

    mFoundIndex = true;
@@ -720,7 +739,9 @@ status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) {
    off64_t offset;
    size_t size;
    bool isKey;
    status_t err = getSampleInfo(trackIndex, 0, &offset, &size, &isKey);
    int64_t timeUs;
    status_t err =
        getSampleInfo(trackIndex, 0, &offset, &size, &isKey, &timeUs);

    if (err != OK) {
        return err;
@@ -762,7 +783,8 @@ status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) {

status_t AVIExtractor::getSampleInfo(
        size_t trackIndex, size_t sampleIndex,
        off64_t *offset, size_t *size, bool *isKey) {
        off64_t *offset, size_t *size, bool *isKey,
        int64_t *sampleTimeUs) {
    if (trackIndex >= mTracks.size()) {
        return -ERANGE;
    }
@@ -801,9 +823,20 @@ status_t AVIExtractor::getSampleInfo(

    *isKey = info.mIsKey;

    *sampleTimeUs = (sampleIndex * 1000000ll * track.mRate) / track.mScale;

    return OK;
}

status_t AVIExtractor::getSampleTime(
        size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs) {
    off64_t offset;
    size_t size;
    bool isKey;
    return getSampleInfo(
            trackIndex, sampleIndex, &offset, &size, &isKey, sampleTimeUs);
}

status_t AVIExtractor::getSampleIndexAtTime(
        size_t trackIndex,
        int64_t timeUs, MediaSource::ReadOptions::SeekMode mode,
+10 −1
Original line number Diff line number Diff line
@@ -54,6 +54,11 @@ private:
        uint32_t mRate;
        uint32_t mScale;

        // If bytes per sample == 0, each chunk represents a single sample,
        // otherwise each chunk should me a multiple of bytes-per-sample in
        // size.
        uint32_t mBytesPerSample;

        enum Kind {
            AUDIO,
            VIDEO,
@@ -84,7 +89,11 @@ private:

    status_t getSampleInfo(
            size_t trackIndex, size_t sampleIndex,
            off64_t *offset, size_t *size, bool *isKey);
            off64_t *offset, size_t *size, bool *isKey,
            int64_t *sampleTimeUs);

    status_t getSampleTime(
            size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs);

    status_t getSampleIndexAtTime(
            size_t trackIndex,