Loading media/libmediaplayerservice/nuplayer/NuPlayer.cpp +55 −20 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ NuPlayer::NuPlayer() mVideoEOS(false), mScanSourcesPending(false), mScanSourcesGeneration(0), mTimeDiscontinuityPending(false), mFlushingAudio(NONE), mFlushingVideo(NONE), mResetInProgress(false), Loading Loading @@ -477,6 +478,8 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { break; } mTimeDiscontinuityPending = true; if (mAudioDecoder != NULL) { flushDecoder(true /* audio */, true /* needShutdown */); } Loading Loading @@ -540,7 +543,10 @@ void NuPlayer::finishFlushIfPossible() { LOGV("both audio and video are flushed now."); if (mTimeDiscontinuityPending) { mRenderer->signalTimeDiscontinuity(); mTimeDiscontinuityPending = false; } if (mAudioDecoder != NULL) { mAudioDecoder->signalResume(); Loading Loading @@ -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)); bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; LOGV("%s discontinuity (formatChange=%d)", audio ? "audio" : "video", formatChange); LOGI("%s discontinuity (formatChange=%d, time=%d)", audio ? "audio" : "video", formatChange, timeChange); if (audio) { mSkipRenderingAudioUntilMediaTimeUs = -1; Loading @@ -674,6 +685,7 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { mSkipRenderingVideoUntilMediaTimeUs = -1; } if (timeChange) { sp<AMessage> extra; if (accessUnit->meta()->findMessage("extra", &extra) && extra != NULL) { Loading @@ -692,8 +704,26 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { } } } } 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); Loading Loading @@ -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; Loading media/libmediaplayerservice/nuplayer/NuPlayer.h +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading media/libstagefright/mpeg2ts/ATSParser.cpp +54 −31 Original line number Diff line number Diff line Loading @@ -123,6 +123,9 @@ private: void extractAACFrames(const sp<ABuffer> &buffer); bool isAudio() const; bool isVideo() const; DISALLOW_EVIL_CONSTRUCTORS(Stream); }; Loading Loading @@ -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: Loading Loading @@ -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) { Loading @@ -495,14 +523,20 @@ void ATSParser::Stream::signalDiscontinuity( mPayloadStarted = false; mBuffer->setRange(0, 0); switch (type) { case DISCONTINUITY_SEEK: case DISCONTINUITY_FORMATCHANGE: { bool isASeek = (type == DISCONTINUITY_SEEK); bool clearFormat = false; if (isAudio()) { if (type & DISCONTINUITY_AUDIO_FORMAT) { clearFormat = true; } } else { if (type & DISCONTINUITY_VIDEO_FORMAT) { clearFormat = true; } } mQueue->clear(!isASeek); mQueue->clear(clearFormat); if (type & DISCONTINUITY_TIME) { uint64_t resumeAtPTS; if (extra != NULL && extra->findInt64( Loading @@ -513,17 +547,11 @@ void ATSParser::Stream::signalDiscontinuity( extra->setInt64("resume-at-mediatimeUs", resumeAtMediaTimeUs); } } if (mSource != NULL) { mSource->queueDiscontinuity(type, extra); } break; } default: TRESPASS(); break; } } void ATSParser::Stream::signalEOS(status_t finalResult) { Loading Loading @@ -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; Loading @@ -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; Loading media/libstagefright/mpeg2ts/ATSParser.h +13 −4 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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, }; Loading media/libstagefright/mpeg2ts/AnotherPacketSource.cpp +21 −4 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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(); } Loading Loading @@ -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(); } Loading @@ -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) { Loading Loading
media/libmediaplayerservice/nuplayer/NuPlayer.cpp +55 −20 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ NuPlayer::NuPlayer() mVideoEOS(false), mScanSourcesPending(false), mScanSourcesGeneration(0), mTimeDiscontinuityPending(false), mFlushingAudio(NONE), mFlushingVideo(NONE), mResetInProgress(false), Loading Loading @@ -477,6 +478,8 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { break; } mTimeDiscontinuityPending = true; if (mAudioDecoder != NULL) { flushDecoder(true /* audio */, true /* needShutdown */); } Loading Loading @@ -540,7 +543,10 @@ void NuPlayer::finishFlushIfPossible() { LOGV("both audio and video are flushed now."); if (mTimeDiscontinuityPending) { mRenderer->signalTimeDiscontinuity(); mTimeDiscontinuityPending = false; } if (mAudioDecoder != NULL) { mAudioDecoder->signalResume(); Loading Loading @@ -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)); bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; LOGV("%s discontinuity (formatChange=%d)", audio ? "audio" : "video", formatChange); LOGI("%s discontinuity (formatChange=%d, time=%d)", audio ? "audio" : "video", formatChange, timeChange); if (audio) { mSkipRenderingAudioUntilMediaTimeUs = -1; Loading @@ -674,6 +685,7 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { mSkipRenderingVideoUntilMediaTimeUs = -1; } if (timeChange) { sp<AMessage> extra; if (accessUnit->meta()->findMessage("extra", &extra) && extra != NULL) { Loading @@ -692,8 +704,26 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { } } } } 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); Loading Loading @@ -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; Loading
media/libmediaplayerservice/nuplayer/NuPlayer.h +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
media/libstagefright/mpeg2ts/ATSParser.cpp +54 −31 Original line number Diff line number Diff line Loading @@ -123,6 +123,9 @@ private: void extractAACFrames(const sp<ABuffer> &buffer); bool isAudio() const; bool isVideo() const; DISALLOW_EVIL_CONSTRUCTORS(Stream); }; Loading Loading @@ -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: Loading Loading @@ -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) { Loading @@ -495,14 +523,20 @@ void ATSParser::Stream::signalDiscontinuity( mPayloadStarted = false; mBuffer->setRange(0, 0); switch (type) { case DISCONTINUITY_SEEK: case DISCONTINUITY_FORMATCHANGE: { bool isASeek = (type == DISCONTINUITY_SEEK); bool clearFormat = false; if (isAudio()) { if (type & DISCONTINUITY_AUDIO_FORMAT) { clearFormat = true; } } else { if (type & DISCONTINUITY_VIDEO_FORMAT) { clearFormat = true; } } mQueue->clear(!isASeek); mQueue->clear(clearFormat); if (type & DISCONTINUITY_TIME) { uint64_t resumeAtPTS; if (extra != NULL && extra->findInt64( Loading @@ -513,17 +547,11 @@ void ATSParser::Stream::signalDiscontinuity( extra->setInt64("resume-at-mediatimeUs", resumeAtMediaTimeUs); } } if (mSource != NULL) { mSource->queueDiscontinuity(type, extra); } break; } default: TRESPASS(); break; } } void ATSParser::Stream::signalEOS(status_t finalResult) { Loading Loading @@ -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; Loading @@ -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; Loading
media/libstagefright/mpeg2ts/ATSParser.h +13 −4 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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, }; Loading
media/libstagefright/mpeg2ts/AnotherPacketSource.cpp +21 −4 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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(); } Loading Loading @@ -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(); } Loading @@ -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) { Loading