Loading media/libstagefright/include/MPEG2TSExtractor.h +17 −1 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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); Loading @@ -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); }; }; Loading media/libstagefright/mpeg2ts/ATSParser.cpp +13 −6 Original line number Original line Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; Loading Loading @@ -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( Loading Loading @@ -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; Loading Loading @@ -697,7 +701,7 @@ status_t ATSParser::Stream::parse( } } mPayloadStarted = true; mPayloadStarted = true; mPesStartOffset = offset; mPesStartOffsets.push_back(offset); } } if (!mPayloadStarted) { if (!mPayloadStarted) { Loading Loading @@ -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); Loading Loading @@ -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()); } } } } } } Loading media/libstagefright/mpeg2ts/ATSParser.h +9 −7 Original line number Original line Diff line number Diff line Loading @@ -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. */ Loading media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp +37 −19 Original line number Original line Diff line number Diff line Loading @@ -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(); } } Loading Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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]; Loading @@ -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); Loading @@ -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; Loading Loading
media/libstagefright/include/MPEG2TSExtractor.h +17 −1 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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); Loading @@ -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); }; }; Loading
media/libstagefright/mpeg2ts/ATSParser.cpp +13 −6 Original line number Original line Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; Loading Loading @@ -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( Loading Loading @@ -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; Loading Loading @@ -697,7 +701,7 @@ status_t ATSParser::Stream::parse( } } mPayloadStarted = true; mPayloadStarted = true; mPesStartOffset = offset; mPesStartOffsets.push_back(offset); } } if (!mPayloadStarted) { if (!mPayloadStarted) { Loading Loading @@ -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); Loading Loading @@ -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()); } } } } } } Loading
media/libstagefright/mpeg2ts/ATSParser.h +9 −7 Original line number Original line Diff line number Diff line Loading @@ -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. */ Loading
media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp +37 −19 Original line number Original line Diff line number Diff line Loading @@ -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(); } } Loading Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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]; Loading @@ -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); Loading @@ -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; Loading