diff options
-rw-r--r-- | include/media/stagefright/foundation/ADebug.h | 5 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 12 | ||||
-rw-r--r-- | media/libstagefright/httplive/LiveSession.cpp | 17 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/ATSParser.cpp | 85 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/ATSParser.h | 1 |
5 files changed, 100 insertions, 20 deletions
diff --git a/include/media/stagefright/foundation/ADebug.h b/include/media/stagefright/foundation/ADebug.h index eb5e494..450dcfe 100644 --- a/include/media/stagefright/foundation/ADebug.h +++ b/include/media/stagefright/foundation/ADebug.h @@ -75,7 +75,10 @@ MAKE_COMPARATOR(GT,>) #define CHECK_GE(x,y) CHECK_OP(x,y,GE,>=) #define CHECK_GT(x,y) CHECK_OP(x,y,GT,>) -#define TRESPASS() LOG_ALWAYS_FATAL("Should not be here.") +#define TRESPASS() \ + LOG_ALWAYS_FATAL( \ + __FILE__ ":" LITERAL_TO_STRING(__LINE__) \ + " Should not be here."); } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 93e5c14..369a3a8 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -40,9 +40,9 @@ NuPlayer::Renderer::Renderer( mAnchorTimeRealUs(-1), mFlushingAudio(false), mFlushingVideo(false), - mHasAudio(mAudioSink != NULL), - mHasVideo(true), - mSyncQueues(mHasAudio && mHasVideo), + mHasAudio(false), + mHasVideo(false), + mSyncQueues(false), mPaused(false) { } @@ -360,6 +360,12 @@ void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) { int32_t audio; CHECK(msg->findInt32("audio", &audio)); + if (audio) { + mHasAudio = true; + } else { + mHasVideo = true; + } + if (dropBufferWhileFlushing(audio, msg)) { return; } diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp index f20a4cb..c6c36e3 100644 --- a/media/libstagefright/httplive/LiveSession.cpp +++ b/media/libstagefright/httplive/LiveSession.cpp @@ -506,8 +506,21 @@ rinse_repeat: LOGE("This doesn't look like a transport stream..."); - mDataSource->queueEOS(ERROR_UNSUPPORTED); - return; + mBandwidthItems.removeAt(bandwidthIndex); + + if (mBandwidthItems.isEmpty()) { + mDataSource->queueEOS(ERROR_UNSUPPORTED); + return; + } + + LOGI("Retrying with a different bandwidth stream."); + + mLastPlaylistFetchTimeUs = -1; + bandwidthIndex = getBandwidthIndex(); + mPrevBandwidthIndex = bandwidthIndex; + mSeqNumber = -1; + + goto rinse_repeat; } if ((size_t)mPrevBandwidthIndex != bandwidthIndex) { diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index d8ab080..4335b99 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -75,6 +75,10 @@ private: struct ATSParser::Stream : public RefBase { Stream(Program *program, unsigned elementaryPID, unsigned streamType); + unsigned type() const { return mStreamType; } + unsigned pid() const { return mElementaryPID; } + void setPID(unsigned pid) { mElementaryPID = pid; } + void parse( unsigned payload_unit_start_indicator, ABitReader *br); @@ -95,6 +99,7 @@ private: sp<ABuffer> mBuffer; sp<AnotherPacketSource> mSource; bool mPayloadStarted; + DiscontinuityType mPendingDiscontinuity; ElementaryStreamQueue mQueue; @@ -107,6 +112,8 @@ private: void extractAACFrames(const sp<ABuffer> &buffer); + void deferDiscontinuity(DiscontinuityType type); + DISALLOW_EVIL_CONSTRUCTORS(Stream); }; @@ -155,6 +162,11 @@ void ATSParser::Program::signalEOS(status_t finalResult) { } } +struct StreamInfo { + unsigned mType; + unsigned mPID; +}; + void ATSParser::Program::parseProgramMap(ABitReader *br) { unsigned table_id = br->getBits(8); LOGV(" table_id = %u", table_id); @@ -188,6 +200,8 @@ void ATSParser::Program::parseProgramMap(ABitReader *br) { br->skipBits(program_info_length * 8); // skip descriptors + Vector<StreamInfo> infos; + // infoBytesRemaining is the number of bytes that make up the // variable length section of ES_infos. It does not include the // final CRC. @@ -231,24 +245,48 @@ void ATSParser::Program::parseProgramMap(ABitReader *br) { CHECK_EQ(info_bytes_remaining, 0u); #endif - ssize_t index = mStreams.indexOfKey(elementaryPID); -#if 0 // XXX revisit - CHECK_LT(index, 0); - mStreams.add(elementaryPID, - new Stream(this, elementaryPID, streamType)); -#else - if (index < 0) { - mStreams.add(elementaryPID, - new Stream(this, elementaryPID, streamType)); - } -#endif + StreamInfo info; + info.mType = streamType; + info.mPID = elementaryPID; + infos.push(info); infoBytesRemaining -= 5 + ES_info_length; } CHECK_EQ(infoBytesRemaining, 0u); - MY_LOGV(" CRC = 0x%08x", br->getBits(32)); + + bool PIDsChanged = false; + for (size_t i = 0; i < infos.size(); ++i) { + StreamInfo &info = infos.editItemAt(i); + + ssize_t index = mStreams.indexOfKey(info.mPID); + + if (index >= 0 && mStreams.editValueAt(index)->type() != info.mType) { + LOGI("uh oh. stream PIDs have changed."); + PIDsChanged = true; + break; + } + } + + if (PIDsChanged) { + mStreams.clear(); + } + + for (size_t i = 0; i < infos.size(); ++i) { + StreamInfo &info = infos.editItemAt(i); + + ssize_t index = mStreams.indexOfKey(info.mPID); + + if (index < 0) { + sp<Stream> stream = new Stream(this, info.mPID, info.mType); + mStreams.add(info.mPID, stream); + + if (PIDsChanged) { + stream->signalDiscontinuity(DISCONTINUITY_FORMATCHANGE); + } + } + } } sp<MediaSource> ATSParser::Program::getSource(SourceType type) { @@ -290,6 +328,7 @@ ATSParser::Stream::Stream( mStreamType(streamType), mBuffer(new ABuffer(192 * 1024)), mPayloadStarted(false), + mPendingDiscontinuity(DISCONTINUITY_NONE), mQueue(streamType == 0x1b ? ElementaryStreamQueue::H264 : ElementaryStreamQueue::AAC) { mBuffer->setRange(0, 0); @@ -336,9 +375,13 @@ void ATSParser::Stream::signalDiscontinuity(DiscontinuityType type) { { mQueue.clear(true); - if (mStreamType == 0x1b && mSource != NULL) { + if (mStreamType == 0x1b) { // Don't signal discontinuities on audio streams. - mSource->queueDiscontinuity(type); + if (mSource != NULL) { + mSource->queueDiscontinuity(type); + } else { + deferDiscontinuity(type); + } } break; } @@ -352,6 +395,8 @@ void ATSParser::Stream::signalDiscontinuity(DiscontinuityType type) { if (mSource != NULL) { mSource->queueDiscontinuity(type); + } else { + deferDiscontinuity(type); } break; } @@ -362,6 +407,13 @@ void ATSParser::Stream::signalDiscontinuity(DiscontinuityType type) { } } +void ATSParser::Stream::deferDiscontinuity(DiscontinuityType type) { + if (type > mPendingDiscontinuity) { + // Only upgrade discontinuities. + mPendingDiscontinuity = type; + } +} + void ATSParser::Stream::signalEOS(status_t finalResult) { if (mSource != NULL) { mSource->signalEOS(finalResult); @@ -558,6 +610,11 @@ void ATSParser::Stream::onPayloadData( LOGV("created source!"); mSource = new AnotherPacketSource(meta); + if (mPendingDiscontinuity != DISCONTINUITY_NONE) { + mSource->queueDiscontinuity(mPendingDiscontinuity); + mPendingDiscontinuity = DISCONTINUITY_NONE; + } + mSource->queueAccessUnit(accessUnit); } } else if (mQueue.getFormat() != NULL) { diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h index fe31981..ec3be84 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.h +++ b/media/libstagefright/mpeg2ts/ATSParser.h @@ -33,6 +33,7 @@ struct MediaSource; struct ATSParser : public RefBase { enum DiscontinuityType { + DISCONTINUITY_NONE, DISCONTINUITY_HTTPLIVE, DISCONTINUITY_SEEK, DISCONTINUITY_FORMATCHANGE |