summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp75
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h4
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.cpp85
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.h17
-rw-r--r--media/libstagefright/mpeg2ts/AnotherPacketSource.cpp25
-rw-r--r--media/libstagefright/mpeg2ts/AnotherPacketSource.h3
-rw-r--r--media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp2
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: