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

Commit 369c3a57 authored by Andreas Huber's avatar Andreas Huber Committed by Android Git Automerger
Browse files

am f2e12498: Merge "Properly identify how much metadata we need to cache in...

am f2e12498: Merge "Properly identify how much metadata we need to cache in order to instantiate" into ics-mr1

* commit 'f2e1249846a17c69d728189a8dc67f37261f0a59':
  Properly identify how much metadata we need to cache in order to instantiate
parents 72028075 a0f2bf56
Loading
Loading
Loading
Loading
+40 −3
Original line number Original line Diff line number Diff line
@@ -1949,6 +1949,8 @@ status_t AwesomePlayer::finishSetDataSource_l() {
        mUri = newURI;
        mUri = newURI;
    }
    }


    AString sniffedMIME;

    if (!strncasecmp("http://", mUri.string(), 7)
    if (!strncasecmp("http://", mUri.string(), 7)
            || !strncasecmp("https://", mUri.string(), 8)
            || !strncasecmp("https://", mUri.string(), 8)
            || isWidevineStreaming) {
            || isWidevineStreaming) {
@@ -1998,7 +2000,6 @@ status_t AwesomePlayer::finishSetDataSource_l() {


        mConnectingDataSource.clear();
        mConnectingDataSource.clear();



        String8 contentType = dataSource->getMIMEType();
        String8 contentType = dataSource->getMIMEType();


        if (strncasecmp(contentType.string(), "audio/", 6)) {
        if (strncasecmp(contentType.string(), "audio/", 6)) {
@@ -2020,16 +2021,51 @@ status_t AwesomePlayer::finishSetDataSource_l() {


                mLock.unlock();
                mLock.unlock();


                // Initially make sure we have at least 128 bytes for the sniff
                // to complete without blocking.
                static const size_t kMinBytesForSniffing = 128;

                off64_t metaDataSize = -1ll;
                for (;;) {
                for (;;) {
                    status_t finalStatus;
                    status_t finalStatus;
                    size_t cachedDataRemaining =
                    size_t cachedDataRemaining =
                        mCachedSource->approxDataRemaining(&finalStatus);
                        mCachedSource->approxDataRemaining(&finalStatus);


                    if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
                    if (finalStatus != OK
                            || (metaDataSize >= 0
                                && cachedDataRemaining >= metaDataSize)
                            || (mFlags & PREPARE_CANCELLED)) {
                            || (mFlags & PREPARE_CANCELLED)) {
                        break;
                        break;
                    }
                    }


                    LOGV("now cached %d bytes of data", cachedDataRemaining);

                    if (metaDataSize < 0
                            && cachedDataRemaining >= kMinBytesForSniffing) {
                        String8 tmp;
                        float confidence;
                        sp<AMessage> meta;
                        if (!dataSource->sniff(&tmp, &confidence, &meta)) {
                            mLock.lock();
                            return UNKNOWN_ERROR;
                        }

                        // We successfully identified the file's extractor to
                        // be, remember this mime type so we don't have to
                        // sniff it again when we call MediaExtractor::Create()
                        // below.
                        sniffedMIME = tmp.string();

                        if (meta == NULL
                                || !meta->findInt64(
                                    "meta-data-size", &metaDataSize)) {
                            metaDataSize = kHighWaterMarkBytes;
                        }

                        CHECK_GE(metaDataSize, 0ll);
                        LOGV("metaDataSize = %lld bytes", metaDataSize);
                    }

                    usleep(200000);
                    usleep(200000);
                }
                }


@@ -2067,7 +2103,8 @@ status_t AwesomePlayer::finishSetDataSource_l() {
        mWVMExtractor->setAdaptiveStreamingMode(true);
        mWVMExtractor->setAdaptiveStreamingMode(true);
        extractor = mWVMExtractor;
        extractor = mWVMExtractor;
    } else {
    } else {
        extractor = MediaExtractor::Create(dataSource);
        extractor = MediaExtractor::Create(
                dataSource, sniffedMIME.empty() ? NULL : sniffedMIME.c_str());


        if (extractor == NULL) {
        if (extractor == NULL) {
            return UNKNOWN_ERROR;
            return UNKNOWN_ERROR;
+94 −23
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@
#include <string.h>
#include <string.h>


#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaBufferGroup.h>
@@ -2301,51 +2302,121 @@ static bool isCompatibleBrand(uint32_t fourcc) {


// Attempt to actually parse the 'ftyp' atom and determine if a suitable
// Attempt to actually parse the 'ftyp' atom and determine if a suitable
// compatible brand is present.
// compatible brand is present.
// Also try to identify where this file's metadata ends
// (end of the 'moov' atom) and report it to the caller as part of
// the metadata.
static bool BetterSniffMPEG4(
static bool BetterSniffMPEG4(
        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
        const sp<DataSource> &source, String8 *mimeType, float *confidence,
    uint8_t header[12];
        sp<AMessage> *meta) {
    if (source->readAt(0, header, 12) != 12
    // We scan up to 128 bytes to identify this file as an MP4.
            || memcmp("ftyp", &header[4], 4)) {
    static const off64_t kMaxScanOffset = 128ll;

    off64_t offset = 0ll;
    bool foundGoodFileType = false;
    off64_t moovAtomEndOffset = -1ll;
    bool done = false;

    while (!done && offset < kMaxScanOffset) {
        uint32_t hdr[2];
        if (source->readAt(offset, hdr, 8) < 8) {
            return false;
            return false;
        }
        }


    size_t atomSize = U32_AT(&header[0]);
        uint64_t chunkSize = ntohl(hdr[0]);
    if (atomSize < 16 || (atomSize % 4) != 0) {
        uint32_t chunkType = ntohl(hdr[1]);
        off64_t chunkDataOffset = offset + 8;

        if (chunkSize == 1) {
            if (source->readAt(offset + 8, &chunkSize, 8) < 8) {
                return false;
                return false;
            }
            }


    bool success = false;
            chunkSize = ntoh64(chunkSize);
    if (isCompatibleBrand(U32_AT(&header[8]))) {
            chunkDataOffset += 8;
        success = true;

    } else {
            if (chunkSize < 16) {
        size_t numCompatibleBrands = (atomSize - 16) / 4;
                // The smallest valid chunk is 16 bytes long in this case.
        for (size_t i = 0; i < numCompatibleBrands; ++i) {
                return false;
            uint8_t tmp[4];
            }
            if (source->readAt(16 + i * 4, tmp, 4) != 4) {
        } else if (chunkSize < 8) {
            // The smallest valid chunk is 8 bytes long.
            return false;
        }

        off64_t chunkDataSize = offset + chunkSize - chunkDataOffset;

        switch (chunkType) {
            case FOURCC('f', 't', 'y', 'p'):
            {
                if (chunkDataSize < 8) {
                    return false;
                    return false;
                }
                }


            if (isCompatibleBrand(U32_AT(&tmp[0]))) {
                uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4;
                success = true;
                for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
                    if (i == 1) {
                        // Skip this index, it refers to the minorVersion,
                        // not a brand.
                        continue;
                    }

                    uint32_t brand;
                    if (source->readAt(
                                chunkDataOffset + 4 * i, &brand, 4) < 4) {
                        return false;
                    }

                    brand = ntohl(brand);

                    if (isCompatibleBrand(brand)) {
                        foundGoodFileType = true;
                        break;
                    }
                }

                if (!foundGoodFileType) {
                    return false;
                }

                break;
            }

            case FOURCC('m', 'o', 'o', 'v'):
            {
                moovAtomEndOffset = offset + chunkSize;

                done = true;
                break;
                break;
            }
            }

            default:
                break;
        }
        }

        offset += chunkSize;
    }
    }


    if (!success) {
    if (!foundGoodFileType) {
        return false;
        return false;
    }
    }


    *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
    *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
    *confidence = 0.4f;
    *confidence = 0.4f;


    if (moovAtomEndOffset >= 0) {
        *meta = new AMessage;
        (*meta)->setInt64("meta-data-size", moovAtomEndOffset);

        LOGV("found metadata size: %lld", moovAtomEndOffset);
    }

    return true;
    return true;
}
}


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


+2 −15
Original line number Original line Diff line number Diff line
@@ -631,14 +631,7 @@ status_t SampleTable::findSyncSampleNear(
        --left;
        --left;
    }
    }


    uint32_t x;
    uint32_t x = mSyncSamples[left];
    if (mDataSource->readAt(
                mSyncSampleOffset + 8 + left * 4, &x, 4) != 4) {
        return ERROR_IO;
    }

    x = ntohl(x);
    --x;


    if (left + 1 < mNumSyncSamples) {
    if (left + 1 < mNumSyncSamples) {
        uint32_t y = mSyncSamples[left + 1];
        uint32_t y = mSyncSamples[left + 1];
@@ -679,13 +672,7 @@ status_t SampleTable::findSyncSampleNear(
            if (x > start_sample_index) {
            if (x > start_sample_index) {
                CHECK(left > 0);
                CHECK(left > 0);


                if (mDataSource->readAt(
                x = mSyncSamples[left - 1];
                            mSyncSampleOffset + 8 + (left - 1) * 4, &x, 4) != 4) {
                    return ERROR_IO;
                }

                x = ntohl(x);
                --x;


                CHECK(x <= start_sample_index);
                CHECK(x <= start_sample_index);
            }
            }