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

Commit 94f16051 authored by Wei Jia's avatar Wei Jia Committed by android-build-merger
Browse files

Merge "MPEG2TSExtractor: add syncPoint after mSourceImpls has been updated." into nyc-dev

am: a5547e58

* commit 'a5547e58':
  MPEG2TSExtractor: add syncPoint after mSourceImpls has been updated.
parents 4b514d95 a5547e58
Loading
Loading
Loading
Loading
+17 −1
Original line number Original line Diff line number Diff line
@@ -25,6 +25,8 @@
#include <utils/KeyedVector.h>
#include <utils/KeyedVector.h>
#include <utils/Vector.h>
#include <utils/Vector.h>


#include "mpeg2ts/ATSParser.h"

namespace android {
namespace android {


struct AMessage;
struct AMessage;
@@ -55,6 +57,10 @@ private:


    sp<ATSParser> mParser;
    sp<ATSParser> mParser;


    // Used to remember SyncEvent occurred in feedMore() when called from init(),
    // because init() needs to update |mSourceImpls| before adding SyncPoint.
    ATSParser::SyncEvent mLastSyncEvent;

    Vector<sp<AnotherPacketSource> > mSourceImpls;
    Vector<sp<AnotherPacketSource> > mSourceImpls;


    Vector<KeyedVector<int64_t, off64_t> > mSyncPoints;
    Vector<KeyedVector<int64_t, off64_t> > mSyncPoints;
@@ -65,7 +71,14 @@ private:
    off64_t mOffset;
    off64_t mOffset;


    void init();
    void init();
    status_t feedMore();
    // Try to feed more data from source to parser.
    // |isInit| means this function is called inside init(). This is a signal to
    // save SyncEvent so that init() can add SyncPoint after it updates |mSourceImpls|.
    // This function returns OK if expected amount of data is fed from DataSource to
    // parser and is successfully parsed. Otherwise, various error codes could be
    // returned, e.g., ERROR_END_OF_STREAM, or no data availalbe from DataSource, or
    // the data has syntax error during parsing, etc.
    status_t feedMore(bool isInit = false);
    status_t seek(int64_t seekTimeUs,
    status_t seek(int64_t seekTimeUs,
            const MediaSource::ReadOptions::SeekMode& seekMode);
            const MediaSource::ReadOptions::SeekMode& seekMode);
    status_t queueDiscontinuityForSeek(int64_t actualSeekTimeUs);
    status_t queueDiscontinuityForSeek(int64_t actualSeekTimeUs);
@@ -73,6 +86,9 @@ private:


    status_t feedUntilBufferAvailable(const sp<AnotherPacketSource> &impl);
    status_t feedUntilBufferAvailable(const sp<AnotherPacketSource> &impl);


    // Add a SynPoint derived from |event|.
    void addSyncPoint_l(const ATSParser::SyncEvent &event);

    DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSExtractor);
    DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSExtractor);
};
};


+13 −6
Original line number Original line Diff line number Diff line
@@ -122,7 +122,7 @@ struct ATSParser::Stream : public RefBase {
    void setPID(unsigned pid) { mElementaryPID = pid; }
    void setPID(unsigned pid) { mElementaryPID = pid; }


    // Parse the payload and set event when PES with a sync frame is detected.
    // Parse the payload and set event when PES with a sync frame is detected.
    // This method knows when a PES starts; so record mPesStartOffset in that
    // This method knows when a PES starts; so record mPesStartOffsets in that
    // case.
    // case.
    status_t parse(
    status_t parse(
            unsigned continuity_counter,
            unsigned continuity_counter,
@@ -157,7 +157,7 @@ private:
    bool mEOSReached;
    bool mEOSReached;


    uint64_t mPrevPTS;
    uint64_t mPrevPTS;
    off64_t mPesStartOffset;
    List<off64_t> mPesStartOffsets;


    ElementaryStreamQueue *mQueue;
    ElementaryStreamQueue *mQueue;


@@ -205,16 +205,19 @@ private:
};
};


ATSParser::SyncEvent::SyncEvent(off64_t offset)
ATSParser::SyncEvent::SyncEvent(off64_t offset)
    : mInit(false), mOffset(offset), mTimeUs(0) {}
    : mHasReturnedData(false), mOffset(offset), mTimeUs(0) {}


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


void ATSParser::SyncEvent::reset() {
    mHasReturnedData = false;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////


ATSParser::Program::Program(
ATSParser::Program::Program(
@@ -661,6 +664,7 @@ status_t ATSParser::Stream::parse(
        ALOGI("discontinuity on stream pid 0x%04x", mElementaryPID);
        ALOGI("discontinuity on stream pid 0x%04x", mElementaryPID);


        mPayloadStarted = false;
        mPayloadStarted = false;
        mPesStartOffsets.clear();
        mBuffer->setRange(0, 0);
        mBuffer->setRange(0, 0);
        mExpectedContinuityCounter = -1;
        mExpectedContinuityCounter = -1;


@@ -697,7 +701,7 @@ status_t ATSParser::Stream::parse(
        }
        }


        mPayloadStarted = true;
        mPayloadStarted = true;
        mPesStartOffset = offset;
        mPesStartOffsets.push_back(offset);
    }
    }


    if (!mPayloadStarted) {
    if (!mPayloadStarted) {
@@ -772,6 +776,7 @@ void ATSParser::Stream::signalDiscontinuity(
    }
    }


    mPayloadStarted = false;
    mPayloadStarted = false;
    mPesStartOffsets.clear();
    mEOSReached = false;
    mEOSReached = false;
    mBuffer->setRange(0, 0);
    mBuffer->setRange(0, 0);


@@ -1105,7 +1110,9 @@ void ATSParser::Stream::onPayloadData(
                int64_t timeUs;
                int64_t timeUs;
                if (accessUnit->meta()->findInt64("timeUs", &timeUs)) {
                if (accessUnit->meta()->findInt64("timeUs", &timeUs)) {
                    found = true;
                    found = true;
                    event->init(mPesStartOffset, mSource, timeUs);
                    off64_t pesStartOffset = *mPesStartOffsets.begin();
                    event->init(pesStartOffset, mSource, timeUs);
                    mPesStartOffsets.erase(mPesStartOffsets.begin());
                }
                }
            }
            }
        }
        }
+9 −7
Original line number Original line Diff line number Diff line
@@ -69,16 +69,18 @@ struct ATSParser : public RefBase {
        void init(off64_t offset, const sp<MediaSource> &source,
        void init(off64_t offset, const sp<MediaSource> &source,
                int64_t timeUs);
                int64_t timeUs);


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


    private:
    private:
        bool mInit;
        bool mHasReturnedData;
        /*
        /*
         * mInit == false: the current offset
         * mHasReturnedData == false: the current offset (or undefined if the returned data
         * mInit == true: the start offset of sync payload
                                      has been invalidated via reset())
         * mHasReturnedData == true: the start offset of sync payload
         */
         */
        off64_t mOffset;
        off64_t mOffset;
        /* The media source object for this event. */
        /* The media source object for this event. */
+37 −19
Original line number Original line Diff line number Diff line
@@ -112,6 +112,7 @@ status_t MPEG2TSSource::read(
MPEG2TSExtractor::MPEG2TSExtractor(const sp<DataSource> &source)
MPEG2TSExtractor::MPEG2TSExtractor(const sp<DataSource> &source)
    : mDataSource(source),
    : mDataSource(source),
      mParser(new ATSParser),
      mParser(new ATSParser),
      mLastSyncEvent(0),
      mOffset(0) {
      mOffset(0) {
    init();
    init();
}
}
@@ -149,8 +150,10 @@ void MPEG2TSExtractor::init() {
    bool haveVideo = false;
    bool haveVideo = false;
    int64_t startTime = ALooper::GetNowUs();
    int64_t startTime = ALooper::GetNowUs();


    while (feedMore() == OK) {
    while (feedMore(true /* isInit */) == OK) {
        if (haveAudio && haveVideo) {
        if (haveAudio && haveVideo) {
            addSyncPoint_l(mLastSyncEvent);
            mLastSyncEvent.reset();
            break;
            break;
        }
        }
        if (!haveVideo) {
        if (!haveVideo) {
@@ -181,6 +184,9 @@ void MPEG2TSExtractor::init() {
            }
            }
        }
        }


        addSyncPoint_l(mLastSyncEvent);
        mLastSyncEvent.reset();

        // Wait only for 2 seconds to detect audio/video streams.
        // Wait only for 2 seconds to detect audio/video streams.
        if (ALooper::GetNowUs() - startTime > 2000000ll) {
        if (ALooper::GetNowUs() - startTime > 2000000ll) {
            break;
            break;
@@ -245,7 +251,7 @@ void MPEG2TSExtractor::init() {
            haveAudio, haveVideo, ALooper::GetNowUs() - startTime);
            haveAudio, haveVideo, ALooper::GetNowUs() - startTime);
}
}


status_t MPEG2TSExtractor::feedMore() {
status_t MPEG2TSExtractor::feedMore(bool isInit) {
    Mutex::Autolock autoLock(mLock);
    Mutex::Autolock autoLock(mLock);


    uint8_t packet[kTSPacketSize];
    uint8_t packet[kTSPacketSize];
@@ -261,7 +267,21 @@ status_t MPEG2TSExtractor::feedMore() {
    ATSParser::SyncEvent event(mOffset);
    ATSParser::SyncEvent event(mOffset);
    mOffset += n;
    mOffset += n;
    status_t err = mParser->feedTSPacket(packet, kTSPacketSize, &event);
    status_t err = mParser->feedTSPacket(packet, kTSPacketSize, &event);
    if (event.isInit()) {
    if (event.hasReturnedData()) {
        if (isInit) {
            mLastSyncEvent = event;
        } else {
            addSyncPoint_l(event);
        }
    }
    return err;
}

void MPEG2TSExtractor::addSyncPoint_l(const ATSParser::SyncEvent &event) {
    if (!event.hasReturnedData()) {
        return;
    }

    for (size_t i = 0; i < mSourceImpls.size(); ++i) {
    for (size_t i = 0; i < mSourceImpls.size(); ++i) {
        if (mSourceImpls[i].get() == event.getMediaSource().get()) {
        if (mSourceImpls[i].get() == event.getMediaSource().get()) {
            KeyedVector<int64_t, off64_t> *syncPoints = &mSyncPoints.editItemAt(i);
            KeyedVector<int64_t, off64_t> *syncPoints = &mSyncPoints.editItemAt(i);
@@ -281,8 +301,6 @@ status_t MPEG2TSExtractor::feedMore() {
        }
        }
    }
    }
}
}
    return err;
}


uint32_t MPEG2TSExtractor::flags() const {
uint32_t MPEG2TSExtractor::flags() const {
    return CAN_PAUSE | CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD;
    return CAN_PAUSE | CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD;