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

Commit b158c545 authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

Merge "Remove streamability verification, it's taking too long. Also..."

parents 6ed7e70d 4678a6dc
Loading
Loading
Loading
Loading
+5 −86
Original line number Diff line number Diff line
@@ -377,7 +377,7 @@ status_t MPEG4Extractor::readMetaData() {
            mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
        }

        mInitCheck = verifyIfStreamable();
        mInitCheck = OK;
    } else {
        mInitCheck = err;
    }
@@ -1904,7 +1904,7 @@ status_t MPEG4Source::read(

    off64_t offset;
    size_t size;
    uint32_t dts;
    uint32_t cts;
    bool isSyncSample;
    bool newBuffer = false;
    if (mBuffer == NULL) {
@@ -1912,7 +1912,7 @@ status_t MPEG4Source::read(

        status_t err =
            mSampleTable->getMetaDataForSample(
                    mCurrentSampleIndex, &offset, &size, &dts, &isSyncSample);
                    mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample);

        if (err != OK) {
            return err;
@@ -1942,7 +1942,7 @@ status_t MPEG4Source::read(
            mBuffer->set_range(0, size);
            mBuffer->meta_data()->clear();
            mBuffer->meta_data()->setInt64(
                    kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
                    kKeyTime, ((int64_t)cts * 1000000) / mTimescale);

            if (targetSampleTimeUs >= 0) {
                mBuffer->meta_data()->setInt64(
@@ -2060,7 +2060,7 @@ status_t MPEG4Source::read(

        mBuffer->meta_data()->clear();
        mBuffer->meta_data()->setInt64(
                kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
                kKeyTime, ((int64_t)cts * 1000000) / mTimescale);

        if (targetSampleTimeUs >= 0) {
            mBuffer->meta_data()->setInt64(
@@ -2094,87 +2094,6 @@ MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix(
    return NULL;
}

status_t MPEG4Extractor::verifyIfStreamable() {
    if (!(mDataSource->flags() & DataSource::kIsCachingDataSource)) {
        return OK;
    }

    Track *audio = findTrackByMimePrefix("audio/");
    Track *video = findTrackByMimePrefix("video/");

    if (audio == NULL || video == NULL) {
        return OK;
    }

    sp<SampleTable> audioSamples = audio->sampleTable;
    sp<SampleTable> videoSamples = video->sampleTable;

    off64_t maxOffsetDiff = 0;
    int64_t maxOffsetTimeUs = -1;

    for (uint32_t i = 0; i < videoSamples->countSamples(); ++i) {
        off64_t videoOffset;
        uint32_t videoTime;
        bool isSync;
        CHECK_EQ((status_t)OK, videoSamples->getMetaDataForSample(
                    i, &videoOffset, NULL, &videoTime, &isSync));

        int64_t videoTimeUs = (int64_t)(videoTime * 1E6 / video->timescale);

        uint32_t reqAudioTime = (videoTimeUs * audio->timescale) / 1000000;
        uint32_t j;
        if (audioSamples->findSampleAtTime(
            reqAudioTime, &j, SampleTable::kFlagClosest) != OK) {
            continue;
        }

        off64_t audioOffset;
        uint32_t audioTime;
        CHECK_EQ((status_t)OK, audioSamples->getMetaDataForSample(
                    j, &audioOffset, NULL, &audioTime));

        int64_t audioTimeUs = (int64_t)(audioTime * 1E6 / audio->timescale);

        off64_t offsetDiff = videoOffset - audioOffset;
        if (offsetDiff < 0) {
            offsetDiff = -offsetDiff;
        }

#if 0
        printf("%s%d/%d videoTime %.2f secs audioTime %.2f secs "
               "videoOffset %lld audioOffset %lld offsetDiff %lld\n",
               isSync ? "*" : " ",
               i,
               j,
               videoTimeUs / 1E6,
               audioTimeUs / 1E6,
               videoOffset,
               audioOffset,
               offsetDiff);
#endif

        if (offsetDiff > maxOffsetDiff) {
            maxOffsetDiff = offsetDiff;
            maxOffsetTimeUs = videoTimeUs;
        }
    }

#if 0
    printf("max offset diff: %lld at video time: %.2f secs\n",
           maxOffsetDiff, maxOffsetTimeUs / 1E6);
#endif

    if (maxOffsetDiff < 1024 * 1024) {
        return OK;
    }

    LOGE("This content is not streamable, "
         "max offset diff: %lld at video time: %.2f secs",
         maxOffsetDiff, maxOffsetTimeUs / 1E6);

    return ERROR_UNSUPPORTED;
}

static bool LegacySniffMPEG4(
        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
    uint8_t header[8];
+112 −47
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ SampleTable::SampleTable(const sp<DataSource> &source)
      mNumSampleSizes(0),
      mTimeToSampleCount(0),
      mTimeToSample(NULL),
      mSampleTimeEntries(NULL),
      mCompositionTimeDeltaEntries(NULL),
      mNumCompositionTimeDeltaEntries(0),
      mSyncSampleOffset(-1),
@@ -73,6 +74,9 @@ SampleTable::~SampleTable() {
    delete[] mCompositionTimeDeltaEntries;
    mCompositionTimeDeltaEntries = NULL;

    delete[] mSampleTimeEntries;
    mSampleTimeEntries = NULL;

    delete[] mTimeToSample;
    mTimeToSample = NULL;

@@ -381,67 +385,128 @@ uint32_t abs_difference(uint32_t time1, uint32_t time2) {
    return time1 > time2 ? time1 - time2 : time2 - time1;
}

status_t SampleTable::findSampleAtTime(
        uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
    // XXX this currently uses decoding time, instead of composition time.
// static
int SampleTable::CompareIncreasingTime(const void *_a, const void *_b) {
    const SampleTimeEntry *a = (const SampleTimeEntry *)_a;
    const SampleTimeEntry *b = (const SampleTimeEntry *)_b;

    *sample_index = 0;
    if (a->mCompositionTime < b->mCompositionTime) {
        return -1;
    } else if (a->mCompositionTime > b->mCompositionTime) {
        return 1;
    }

    return 0;
}

void SampleTable::buildSampleEntriesTable() {
    Mutex::Autolock autoLock(mLock);

    uint32_t cur_sample = 0;
    uint32_t time = 0;
    if (mSampleTimeEntries != NULL) {
        return;
    }

    mSampleTimeEntries = new SampleTimeEntry[mNumSampleSizes];

    uint32_t sampleIndex = 0;
    uint32_t sampleTime = 0;

    for (uint32_t i = 0; i < mTimeToSampleCount; ++i) {
        uint32_t n = mTimeToSample[2 * i];
        uint32_t delta = mTimeToSample[2 * i + 1];

        if (req_time < time + n * delta) {
            int j = (req_time - time) / delta;
        for (uint32_t j = 0; j < n; ++j) {
            CHECK(sampleIndex < mNumSampleSizes);

            mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;

            mSampleTimeEntries[sampleIndex].mCompositionTime =
                sampleTime + getCompositionTimeOffset(sampleIndex);

            ++sampleIndex;
            sampleTime += delta;
        }
    }

            uint32_t time1 = time + j * delta;
            uint32_t time2 = time1 + delta;
    qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry),
          CompareIncreasingTime);
}

            uint32_t sampleTime;
            if (i+1 == mTimeToSampleCount
                    || (abs_difference(req_time, time1)
                        < abs_difference(req_time, time2))) {
                *sample_index = cur_sample + j;
                sampleTime = time1;
status_t SampleTable::findSampleAtTime(
        uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
    buildSampleEntriesTable();

    uint32_t left = 0;
    uint32_t right = mNumSampleSizes;
    while (left < right) {
        uint32_t center = (left + right) / 2;
        uint32_t centerTime = mSampleTimeEntries[center].mCompositionTime;

        if (req_time < centerTime) {
            right = center;
        } else if (req_time > centerTime) {
            left = center + 1;
        } else {
                *sample_index = cur_sample + j + 1;
                sampleTime = time2;
            left = center;
            break;
        }
    }

    if (left == mNumSampleSizes) {
        --left;
    }

    uint32_t closestIndex = left;

    switch (flags) {
        case kFlagBefore:
        {
                    if (sampleTime > req_time && *sample_index > 0) {
                        --*sample_index;
            while (closestIndex > 0
                    && mSampleTimeEntries[closestIndex].mCompositionTime
                            > req_time) {
                --closestIndex;
            }
            break;
        }

        case kFlagAfter:
        {
                    if (sampleTime < req_time
                            && *sample_index + 1 < mNumSampleSizes) {
                        ++*sample_index;
            while (closestIndex + 1 < mNumSampleSizes
                    && mSampleTimeEntries[closestIndex].mCompositionTime
                            < req_time) {
                ++closestIndex;
            }
            break;
        }

        default:
                    break;
            }
        {
            CHECK(flags == kFlagClosest);

            return OK;
            if (closestIndex > 0) {
                // Check left neighbour and pick closest.
                uint32_t absdiff1 =
                    abs_difference(
                            mSampleTimeEntries[closestIndex].mCompositionTime,
                            req_time);

                uint32_t absdiff2 =
                    abs_difference(
                            mSampleTimeEntries[closestIndex - 1].mCompositionTime,
                            req_time);

                if (absdiff1 > absdiff2) {
                    closestIndex = closestIndex - 1;
                }
            }

        time += delta * n;
        cur_sample += n;
            break;
        }
    }

    return ERROR_OUT_OF_RANGE;
    *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex;

    return OK;
}

status_t SampleTable::findSyncSampleNear(
@@ -613,7 +678,7 @@ status_t SampleTable::getMetaDataForSample(
        uint32_t sampleIndex,
        off64_t *offset,
        size_t *size,
        uint32_t *decodingTime,
        uint32_t *compositionTime,
        bool *isSyncSample) {
    Mutex::Autolock autoLock(mLock);

@@ -630,8 +695,8 @@ status_t SampleTable::getMetaDataForSample(
        *size = mSampleIterator->getSampleSize();
    }

    if (decodingTime) {
        *decodingTime = mSampleIterator->getSampleTime();
    if (compositionTime) {
        *compositionTime = mSampleIterator->getSampleTime();
    }

    if (isSyncSample) {
+0 −2
Original line number Diff line number Diff line
@@ -92,8 +92,6 @@ private:

    Track *findTrackByMimePrefix(const char *mimePrefix);

    status_t verifyIfStreamable();

    MPEG4Extractor(const MPEG4Extractor &);
    MPEG4Extractor &operator=(const MPEG4Extractor &);
};
+11 −1
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ public:
            uint32_t sampleIndex,
            off64_t *offset,
            size_t *size,
            uint32_t *decodingTime,
            uint32_t *compositionTime,
            bool *isSyncSample = NULL);

    enum {
@@ -107,6 +107,12 @@ private:
    uint32_t mTimeToSampleCount;
    uint32_t *mTimeToSample;

    struct SampleTimeEntry {
        uint32_t mSampleIndex;
        uint32_t mCompositionTime;
    };
    SampleTimeEntry *mSampleTimeEntries;

    uint32_t *mCompositionTimeDeltaEntries;
    size_t mNumCompositionTimeDeltaEntries;

@@ -130,6 +136,10 @@ private:

    uint32_t getCompositionTimeOffset(uint32_t sampleIndex) const;

    static int CompareIncreasingTime(const void *, const void *);

    void buildSampleEntriesTable();

    SampleTable(const SampleTable &);
    SampleTable &operator=(const SampleTable &);
};