diff options
author | Andreas Huber <andih@google.com> | 2011-11-29 14:08:13 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-11-29 14:08:13 -0800 |
commit | 405a4e34032f8a07028138266fe9f79f6753b466 (patch) | |
tree | 62352e960b6fe93d856304089387041104d706ac /media | |
parent | be6ab576ff0e3bf2a8dc3feee6f476061afbda30 (diff) | |
parent | 66a051af37c3d7a610802c0c58906dc0faefa6be (diff) | |
download | frameworks_base-405a4e34032f8a07028138266fe9f79f6753b466.zip frameworks_base-405a4e34032f8a07028138266fe9f79f6753b466.tar.gz frameworks_base-405a4e34032f8a07028138266fe9f79f6753b466.tar.bz2 |
Merge "Finer granularity discontinuity support." into ics-mr1
Diffstat (limited to 'media')
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 75 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.h | 4 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/ATSParser.cpp | 85 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/ATSParser.h | 17 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/AnotherPacketSource.cpp | 25 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/AnotherPacketSource.h | 3 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp | 2 |
7 files changed, 151 insertions, 60 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 2a5c0a6..ea907c9 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -54,6 +54,7 @@ NuPlayer::NuPlayer() mVideoEOS(false), mScanSourcesPending(false), mScanSourcesGeneration(0), + mTimeDiscontinuityPending(false), mFlushingAudio(NONE), mFlushingVideo(NONE), mResetInProgress(false), @@ -477,6 +478,8 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { break; } + mTimeDiscontinuityPending = true; + if (mAudioDecoder != NULL) { flushDecoder(true /* audio */, true /* needShutdown */); } @@ -540,7 +543,10 @@ void NuPlayer::finishFlushIfPossible() { LOGV("both audio and video are flushed now."); - mRenderer->signalTimeDiscontinuity(); + if (mTimeDiscontinuityPending) { + mRenderer->signalTimeDiscontinuity(); + mTimeDiscontinuityPending = false; + } if (mAudioDecoder != NULL) { mAudioDecoder->signalResume(); @@ -663,10 +669,15 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); bool formatChange = - type == ATSParser::DISCONTINUITY_FORMATCHANGE; + (audio && + (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) + || (!audio && + (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); - LOGV("%s discontinuity (formatChange=%d)", - audio ? "audio" : "video", formatChange); + bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; + + LOGI("%s discontinuity (formatChange=%d, time=%d)", + audio ? "audio" : "video", formatChange, timeChange); if (audio) { mSkipRenderingAudioUntilMediaTimeUs = -1; @@ -674,26 +685,45 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { mSkipRenderingVideoUntilMediaTimeUs = -1; } - sp<AMessage> extra; - if (accessUnit->meta()->findMessage("extra", &extra) - && extra != NULL) { - int64_t resumeAtMediaTimeUs; - if (extra->findInt64( - "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) { - LOGI("suppressing rendering of %s until %lld us", - audio ? "audio" : "video", resumeAtMediaTimeUs); - - if (audio) { - mSkipRenderingAudioUntilMediaTimeUs = - resumeAtMediaTimeUs; - } else { - mSkipRenderingVideoUntilMediaTimeUs = - resumeAtMediaTimeUs; + if (timeChange) { + sp<AMessage> extra; + if (accessUnit->meta()->findMessage("extra", &extra) + && extra != NULL) { + int64_t resumeAtMediaTimeUs; + if (extra->findInt64( + "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) { + LOGI("suppressing rendering of %s until %lld us", + audio ? "audio" : "video", resumeAtMediaTimeUs); + + if (audio) { + mSkipRenderingAudioUntilMediaTimeUs = + resumeAtMediaTimeUs; + } else { + mSkipRenderingVideoUntilMediaTimeUs = + resumeAtMediaTimeUs; + } } } } - flushDecoder(audio, formatChange); + mTimeDiscontinuityPending = + mTimeDiscontinuityPending || timeChange; + + if (formatChange || timeChange) { + flushDecoder(audio, formatChange); + } else { + // This stream is unaffected by the discontinuity + + if (audio) { + mFlushingAudio = FLUSHED; + } else { + mFlushingVideo = FLUSHED; + } + + finishFlushIfPossible(); + + return -EWOULDBLOCK; + } } reply->setInt32("err", err); @@ -794,6 +824,11 @@ void NuPlayer::notifyListener(int msg, int ext1, int ext2) { } void NuPlayer::flushDecoder(bool audio, bool needShutdown) { + if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) { + LOGI("flushDecoder %s without decoder present", + audio ? "audio" : "video"); + } + // Make sure we don't continue to scan sources until we finish flushing. ++mScanSourcesGeneration; mScanSourcesPending = false; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index f23deea..ffc710e 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -112,6 +112,10 @@ private: SHUT_DOWN, }; + // Once the current flush is complete this indicates whether the + // notion of time has changed. + bool mTimeDiscontinuityPending; + FlushStatus mFlushingAudio; FlushStatus mFlushingVideo; bool mResetInProgress; diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index 72f1282..6cec63a 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -123,6 +123,9 @@ private: void extractAACFrames(const sp<ABuffer> &buffer); + bool isAudio() const; + bool isVideo() const; + DISALLOW_EVIL_CONSTRUCTORS(Stream); }; @@ -401,7 +404,7 @@ ATSParser::Stream::Stream( case STREAMTYPE_H264: mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::H264); break; - case STREAMTYPE_MPEG2_AUDIO_ATDS: + case STREAMTYPE_MPEG2_AUDIO_ADTS: mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::AAC); break; case STREAMTYPE_MPEG1_AUDIO: @@ -486,6 +489,31 @@ status_t ATSParser::Stream::parse( return OK; } +bool ATSParser::Stream::isVideo() const { + switch (mStreamType) { + case STREAMTYPE_H264: + case STREAMTYPE_MPEG1_VIDEO: + case STREAMTYPE_MPEG2_VIDEO: + case STREAMTYPE_MPEG4_VIDEO: + return true; + + default: + return false; + } +} + +bool ATSParser::Stream::isAudio() const { + switch (mStreamType) { + case STREAMTYPE_MPEG1_AUDIO: + case STREAMTYPE_MPEG2_AUDIO: + case STREAMTYPE_MPEG2_AUDIO_ADTS: + return true; + + default: + return false; + } +} + void ATSParser::Stream::signalDiscontinuity( DiscontinuityType type, const sp<AMessage> &extra) { if (mQueue == NULL) { @@ -495,34 +523,34 @@ void ATSParser::Stream::signalDiscontinuity( mPayloadStarted = false; mBuffer->setRange(0, 0); - switch (type) { - case DISCONTINUITY_SEEK: - case DISCONTINUITY_FORMATCHANGE: - { - bool isASeek = (type == DISCONTINUITY_SEEK); - - mQueue->clear(!isASeek); + bool clearFormat = false; + if (isAudio()) { + if (type & DISCONTINUITY_AUDIO_FORMAT) { + clearFormat = true; + } + } else { + if (type & DISCONTINUITY_VIDEO_FORMAT) { + clearFormat = true; + } + } - uint64_t resumeAtPTS; - if (extra != NULL - && extra->findInt64( - IStreamListener::kKeyResumeAtPTS, - (int64_t *)&resumeAtPTS)) { - int64_t resumeAtMediaTimeUs = - mProgram->convertPTSToTimestamp(resumeAtPTS); + mQueue->clear(clearFormat); - extra->setInt64("resume-at-mediatimeUs", resumeAtMediaTimeUs); - } + if (type & DISCONTINUITY_TIME) { + uint64_t resumeAtPTS; + if (extra != NULL + && extra->findInt64( + IStreamListener::kKeyResumeAtPTS, + (int64_t *)&resumeAtPTS)) { + int64_t resumeAtMediaTimeUs = + mProgram->convertPTSToTimestamp(resumeAtPTS); - if (mSource != NULL) { - mSource->queueDiscontinuity(type, extra); - } - break; + extra->setInt64("resume-at-mediatimeUs", resumeAtMediaTimeUs); } + } - default: - TRESPASS(); - break; + if (mSource != NULL) { + mSource->queueDiscontinuity(type, extra); } } @@ -764,10 +792,7 @@ sp<MediaSource> ATSParser::Stream::getSource(SourceType type) { switch (type) { case VIDEO: { - if (mStreamType == STREAMTYPE_H264 - || mStreamType == STREAMTYPE_MPEG1_VIDEO - || mStreamType == STREAMTYPE_MPEG2_VIDEO - || mStreamType == STREAMTYPE_MPEG4_VIDEO) { + if (isVideo()) { return mSource; } break; @@ -775,9 +800,7 @@ sp<MediaSource> ATSParser::Stream::getSource(SourceType type) { case AUDIO: { - if (mStreamType == STREAMTYPE_MPEG1_AUDIO - || mStreamType == STREAMTYPE_MPEG2_AUDIO - || mStreamType == STREAMTYPE_MPEG2_AUDIO_ATDS) { + if (isAudio()) { return mSource; } break; diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h index 878e534..c8038d1 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.h +++ b/media/libstagefright/mpeg2ts/ATSParser.h @@ -33,9 +33,18 @@ struct MediaSource; struct ATSParser : public RefBase { enum DiscontinuityType { - DISCONTINUITY_NONE, - DISCONTINUITY_SEEK, - DISCONTINUITY_FORMATCHANGE + DISCONTINUITY_NONE = 0, + DISCONTINUITY_TIME = 1, + DISCONTINUITY_AUDIO_FORMAT = 2, + DISCONTINUITY_VIDEO_FORMAT = 4, + + DISCONTINUITY_SEEK = DISCONTINUITY_TIME, + + // For legacy reasons this also implies a time discontinuity. + DISCONTINUITY_FORMATCHANGE = + DISCONTINUITY_AUDIO_FORMAT + | DISCONTINUITY_VIDEO_FORMAT + | DISCONTINUITY_TIME, }; enum Flags { @@ -71,7 +80,7 @@ struct ATSParser : public RefBase { STREAMTYPE_MPEG2_VIDEO = 0x02, STREAMTYPE_MPEG1_AUDIO = 0x03, STREAMTYPE_MPEG2_AUDIO = 0x04, - STREAMTYPE_MPEG2_AUDIO_ATDS = 0x0f, + STREAMTYPE_MPEG2_AUDIO_ADTS = 0x0f, STREAMTYPE_MPEG4_VIDEO = 0x10, STREAMTYPE_H264 = 0x1b, }; diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp index ce07e32..f782ce5 100644 --- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp +++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp @@ -29,8 +29,17 @@ namespace android { AnotherPacketSource::AnotherPacketSource(const sp<MetaData> &meta) - : mFormat(meta), + : mIsAudio(false), + mFormat(meta), mEOSResult(OK) { + const char *mime; + CHECK(meta->findCString(kKeyMIMEType, &mime)); + + if (!strncasecmp("audio/", mime, 6)) { + mIsAudio = true; + } else { + CHECK(!strncasecmp("video/", mime, 6)); + } } void AnotherPacketSource::setFormat(const sp<MetaData> &meta) { @@ -67,8 +76,7 @@ status_t AnotherPacketSource::dequeueAccessUnit(sp<ABuffer> *buffer) { int32_t discontinuity; if ((*buffer)->meta()->findInt32("discontinuity", &discontinuity)) { - - if (discontinuity == ATSParser::DISCONTINUITY_FORMATCHANGE) { + if (wasFormatChange(discontinuity)) { mFormat.clear(); } @@ -96,7 +104,7 @@ status_t AnotherPacketSource::read( int32_t discontinuity; if (buffer->meta()->findInt32("discontinuity", &discontinuity)) { - if (discontinuity == ATSParser::DISCONTINUITY_FORMATCHANGE) { + if (wasFormatChange(discontinuity)) { mFormat.clear(); } @@ -117,6 +125,15 @@ status_t AnotherPacketSource::read( return mEOSResult; } +bool AnotherPacketSource::wasFormatChange( + int32_t discontinuityType) const { + if (mIsAudio) { + return (discontinuityType & ATSParser::DISCONTINUITY_AUDIO_FORMAT) != 0; + } + + return (discontinuityType & ATSParser::DISCONTINUITY_VIDEO_FORMAT) != 0; +} + void AnotherPacketSource::queueAccessUnit(const sp<ABuffer> &buffer) { int32_t damaged; if (buffer->meta()->findInt32("damaged", &damaged) && damaged) { diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.h b/media/libstagefright/mpeg2ts/AnotherPacketSource.h index 439c785..c99f7f2 100644 --- a/media/libstagefright/mpeg2ts/AnotherPacketSource.h +++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.h @@ -61,10 +61,13 @@ private: Mutex mLock; Condition mCondition; + bool mIsAudio; sp<MetaData> mFormat; List<sp<ABuffer> > mBuffers; status_t mEOSResult; + bool wasFormatChange(int32_t discontinuityType) const; + DISALLOW_EVIL_CONSTRUCTORS(AnotherPacketSource); }; diff --git a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp index f55be6e..a089dbf 100644 --- a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp +++ b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp @@ -543,7 +543,7 @@ MPEG2PSExtractor::Track::Track( case ATSParser::STREAMTYPE_H264: mode = ElementaryStreamQueue::H264; break; - case ATSParser::STREAMTYPE_MPEG2_AUDIO_ATDS: + case ATSParser::STREAMTYPE_MPEG2_AUDIO_ADTS: mode = ElementaryStreamQueue::AAC; break; case ATSParser::STREAMTYPE_MPEG1_AUDIO: |