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

Commit 82e14704 authored by Robert Shih's avatar Robert Shih
Browse files

MPEG2TSExtractor: get duration by seeking to end

Prerequisites for this implementation (included in this commit):
* DataSources:
  + add kIsLocalFileSource flag
* AnotherPacketSource:
  + implement getEstimatedBufferDurationUs
* ATSParser:
  + expose Event SourceType
  + expose first pts

Test: adb shell am start -a android.intent.action.VIEW -n <video player activity> -d <local ts file>
Bug: 31964524
Change-Id: Ifcb6b3246cfa3748ee4d87ed09dbdf62e963a6e5
parent c2d29c48
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ public:
        kStreamedFromLocalHost = 2,
        kIsCachingDataSource   = 4,
        kIsHTTPBasedSource     = 8,
        kIsLocalFileSource     = 16,
    };

    static sp<DataSource> CreateFromURI(
+4 −0
Original line number Diff line number Diff line
@@ -39,6 +39,10 @@ public:

    virtual status_t getSize(off64_t *size);

    virtual uint32_t flags() {
        return kIsLocalFileSource;
    }

    virtual sp<DecryptHandle> DrmInitialization(const char *mime);

    virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
+2 −0
Original line number Diff line number Diff line
@@ -89,6 +89,8 @@ private:
    // Add a SynPoint derived from |event|.
    void addSyncPoint_l(const ATSParser::SyncEvent &event);

    status_t  estimateDurationsFromTimesUsAtEnd();

    DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSExtractor);
};

+29 −2
Original line number Diff line number Diff line
@@ -90,6 +90,10 @@ struct ATSParser::Program : public RefBase {
        return mParser->mFlags;
    }

    uint64_t firstPTS() const {
        return mFirstPTS;
    }

private:
    struct StreamInfo {
        unsigned mType;
@@ -135,6 +139,7 @@ struct ATSParser::Stream : public RefBase {

    void signalEOS(status_t finalResult);

    SourceType getSourceType();
    sp<MediaSource> getSource(SourceType type);

    bool isAudio() const;
@@ -208,11 +213,12 @@ ATSParser::SyncEvent::SyncEvent(off64_t offset)
    : mHasReturnedData(false), mOffset(offset), mTimeUs(0) {}

void ATSParser::SyncEvent::init(off64_t offset, const sp<MediaSource> &source,
        int64_t timeUs) {
        int64_t timeUs, SourceType type) {
    mHasReturnedData = true;
    mOffset = offset;
    mMediaSource = source;
    mTimeUs = timeUs;
    mType = type;
}

void ATSParser::SyncEvent::reset() {
@@ -1121,11 +1127,22 @@ void ATSParser::Stream::onPayloadData(
                int64_t timeUs;
                if (accessUnit->meta()->findInt64("timeUs", &timeUs)) {
                    found = true;
                    event->init(pesStartOffset, mSource, timeUs);
                    event->init(pesStartOffset, mSource, timeUs, getSourceType());
                }
            }
        }
    }
}

ATSParser::SourceType ATSParser::Stream::getSourceType() {
    if (isVideo()) {
        return VIDEO;
    } else if (isAudio()) {
        return AUDIO;
    } else if (isMeta()) {
        return META;
    }
    return NUM_SOURCE_TYPES;
}

sp<MediaSource> ATSParser::Stream::getSource(SourceType type) {
@@ -1565,6 +1582,16 @@ bool ATSParser::PTSTimeDeltaEstablished() {
    return mPrograms.editItemAt(0)->PTSTimeDeltaEstablished();
}

int64_t ATSParser::getFirstPTSTimeUs() {
    for (size_t i = 0; i < mPrograms.size(); ++i) {
        sp<ATSParser::Program> program = mPrograms.itemAt(i);
        if (program->PTSTimeDeltaEstablished()) {
            return (program->firstPTS() * 100) / 9;
        }
    }
    return -1;
}

__attribute__((no_sanitize("integer")))
void ATSParser::updatePCR(
        unsigned /* PID */, uint64_t PCR, uint64_t byteOffsetFromStart) {
+12 −7
Original line number Diff line number Diff line
@@ -62,18 +62,26 @@ struct ATSParser : public RefBase {
        ALIGNED_VIDEO_DATA         = 2,
    };

    enum SourceType {
        VIDEO = 0,
        AUDIO = 1,
        META  = 2,
        NUM_SOURCE_TYPES = 3
    };

    // Event is used to signal sync point event at feedTSPacket().
    struct SyncEvent {
        explicit SyncEvent(off64_t offset);

        void init(off64_t offset, const sp<MediaSource> &source,
                int64_t timeUs);
                int64_t timeUs, SourceType type);

        bool hasReturnedData() const { return mHasReturnedData; }
        void reset();
        off64_t getOffset() const { return mOffset; }
        const sp<MediaSource> &getMediaSource() const { return mMediaSource; }
        int64_t getTimeUs() const { return mTimeUs; }
        SourceType getType() const { return mType; }

    private:
        bool mHasReturnedData;
@@ -87,6 +95,7 @@ struct ATSParser : public RefBase {
        sp<MediaSource> mMediaSource;
        /* The timestamp of the sync frame. */
        int64_t mTimeUs;
        SourceType mType;
    };

    explicit ATSParser(uint32_t flags = 0);
@@ -107,17 +116,13 @@ struct ATSParser : public RefBase {

    void signalEOS(status_t finalResult);

    enum SourceType {
        VIDEO = 0,
        AUDIO = 1,
        META  = 2,
        NUM_SOURCE_TYPES = 3
    };
    sp<MediaSource> getSource(SourceType type);
    bool hasSource(SourceType type) const;

    bool PTSTimeDeltaEstablished();

    int64_t getFirstPTSTimeUs();

    enum {
        // From ISO/IEC 13818-1: 2000 (E), Table 2-29
        STREAMTYPE_RESERVED             = 0x00,
Loading