Skip to content

Commit 405a4e3

Browse files
theandi666Android (Google) Code Review
authored andcommitted
Merge "Finer granularity discontinuity support." into ics-mr1
2 parents be6ab57 + 66a051a commit 405a4e3

File tree

7 files changed

+151
-60
lines changed

7 files changed

+151
-60
lines changed

media/libmediaplayerservice/nuplayer/NuPlayer.cpp

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ NuPlayer::NuPlayer()
5454
mVideoEOS(false),
5555
mScanSourcesPending(false),
5656
mScanSourcesGeneration(0),
57+
mTimeDiscontinuityPending(false),
5758
mFlushingAudio(NONE),
5859
mFlushingVideo(NONE),
5960
mResetInProgress(false),
@@ -477,6 +478,8 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
477478
break;
478479
}
479480

481+
mTimeDiscontinuityPending = true;
482+
480483
if (mAudioDecoder != NULL) {
481484
flushDecoder(true /* audio */, true /* needShutdown */);
482485
}
@@ -540,7 +543,10 @@ void NuPlayer::finishFlushIfPossible() {
540543

541544
LOGV("both audio and video are flushed now.");
542545

543-
mRenderer->signalTimeDiscontinuity();
546+
if (mTimeDiscontinuityPending) {
547+
mRenderer->signalTimeDiscontinuity();
548+
mTimeDiscontinuityPending = false;
549+
}
544550

545551
if (mAudioDecoder != NULL) {
546552
mAudioDecoder->signalResume();
@@ -663,37 +669,61 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
663669
CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
664670

665671
bool formatChange =
666-
type == ATSParser::DISCONTINUITY_FORMATCHANGE;
672+
(audio &&
673+
(type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
674+
|| (!audio &&
675+
(type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
667676

668-
LOGV("%s discontinuity (formatChange=%d)",
669-
audio ? "audio" : "video", formatChange);
677+
bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
678+
679+
LOGI("%s discontinuity (formatChange=%d, time=%d)",
680+
audio ? "audio" : "video", formatChange, timeChange);
670681

671682
if (audio) {
672683
mSkipRenderingAudioUntilMediaTimeUs = -1;
673684
} else {
674685
mSkipRenderingVideoUntilMediaTimeUs = -1;
675686
}
676687

677-
sp<AMessage> extra;
678-
if (accessUnit->meta()->findMessage("extra", &extra)
679-
&& extra != NULL) {
680-
int64_t resumeAtMediaTimeUs;
681-
if (extra->findInt64(
682-
"resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
683-
LOGI("suppressing rendering of %s until %lld us",
684-
audio ? "audio" : "video", resumeAtMediaTimeUs);
685-
686-
if (audio) {
687-
mSkipRenderingAudioUntilMediaTimeUs =
688-
resumeAtMediaTimeUs;
689-
} else {
690-
mSkipRenderingVideoUntilMediaTimeUs =
691-
resumeAtMediaTimeUs;
688+
if (timeChange) {
689+
sp<AMessage> extra;
690+
if (accessUnit->meta()->findMessage("extra", &extra)
691+
&& extra != NULL) {
692+
int64_t resumeAtMediaTimeUs;
693+
if (extra->findInt64(
694+
"resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
695+
LOGI("suppressing rendering of %s until %lld us",
696+
audio ? "audio" : "video", resumeAtMediaTimeUs);
697+
698+
if (audio) {
699+
mSkipRenderingAudioUntilMediaTimeUs =
700+
resumeAtMediaTimeUs;
701+
} else {
702+
mSkipRenderingVideoUntilMediaTimeUs =
703+
resumeAtMediaTimeUs;
704+
}
692705
}
693706
}
694707
}
695708

696-
flushDecoder(audio, formatChange);
709+
mTimeDiscontinuityPending =
710+
mTimeDiscontinuityPending || timeChange;
711+
712+
if (formatChange || timeChange) {
713+
flushDecoder(audio, formatChange);
714+
} else {
715+
// This stream is unaffected by the discontinuity
716+
717+
if (audio) {
718+
mFlushingAudio = FLUSHED;
719+
} else {
720+
mFlushingVideo = FLUSHED;
721+
}
722+
723+
finishFlushIfPossible();
724+
725+
return -EWOULDBLOCK;
726+
}
697727
}
698728

699729
reply->setInt32("err", err);
@@ -794,6 +824,11 @@ void NuPlayer::notifyListener(int msg, int ext1, int ext2) {
794824
}
795825

796826
void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
827+
if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
828+
LOGI("flushDecoder %s without decoder present",
829+
audio ? "audio" : "video");
830+
}
831+
797832
// Make sure we don't continue to scan sources until we finish flushing.
798833
++mScanSourcesGeneration;
799834
mScanSourcesPending = false;

media/libmediaplayerservice/nuplayer/NuPlayer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ struct NuPlayer : public AHandler {
112112
SHUT_DOWN,
113113
};
114114

115+
// Once the current flush is complete this indicates whether the
116+
// notion of time has changed.
117+
bool mTimeDiscontinuityPending;
118+
115119
FlushStatus mFlushingAudio;
116120
FlushStatus mFlushingVideo;
117121
bool mResetInProgress;

media/libstagefright/mpeg2ts/ATSParser.cpp

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ struct ATSParser::Stream : public RefBase {
123123

124124
void extractAACFrames(const sp<ABuffer> &buffer);
125125

126+
bool isAudio() const;
127+
bool isVideo() const;
128+
126129
DISALLOW_EVIL_CONSTRUCTORS(Stream);
127130
};
128131

@@ -401,7 +404,7 @@ ATSParser::Stream::Stream(
401404
case STREAMTYPE_H264:
402405
mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::H264);
403406
break;
404-
case STREAMTYPE_MPEG2_AUDIO_ATDS:
407+
case STREAMTYPE_MPEG2_AUDIO_ADTS:
405408
mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::AAC);
406409
break;
407410
case STREAMTYPE_MPEG1_AUDIO:
@@ -486,6 +489,31 @@ status_t ATSParser::Stream::parse(
486489
return OK;
487490
}
488491

492+
bool ATSParser::Stream::isVideo() const {
493+
switch (mStreamType) {
494+
case STREAMTYPE_H264:
495+
case STREAMTYPE_MPEG1_VIDEO:
496+
case STREAMTYPE_MPEG2_VIDEO:
497+
case STREAMTYPE_MPEG4_VIDEO:
498+
return true;
499+
500+
default:
501+
return false;
502+
}
503+
}
504+
505+
bool ATSParser::Stream::isAudio() const {
506+
switch (mStreamType) {
507+
case STREAMTYPE_MPEG1_AUDIO:
508+
case STREAMTYPE_MPEG2_AUDIO:
509+
case STREAMTYPE_MPEG2_AUDIO_ADTS:
510+
return true;
511+
512+
default:
513+
return false;
514+
}
515+
}
516+
489517
void ATSParser::Stream::signalDiscontinuity(
490518
DiscontinuityType type, const sp<AMessage> &extra) {
491519
if (mQueue == NULL) {
@@ -495,34 +523,34 @@ void ATSParser::Stream::signalDiscontinuity(
495523
mPayloadStarted = false;
496524
mBuffer->setRange(0, 0);
497525

498-
switch (type) {
499-
case DISCONTINUITY_SEEK:
500-
case DISCONTINUITY_FORMATCHANGE:
501-
{
502-
bool isASeek = (type == DISCONTINUITY_SEEK);
503-
504-
mQueue->clear(!isASeek);
526+
bool clearFormat = false;
527+
if (isAudio()) {
528+
if (type & DISCONTINUITY_AUDIO_FORMAT) {
529+
clearFormat = true;
530+
}
531+
} else {
532+
if (type & DISCONTINUITY_VIDEO_FORMAT) {
533+
clearFormat = true;
534+
}
535+
}
505536

506-
uint64_t resumeAtPTS;
507-
if (extra != NULL
508-
&& extra->findInt64(
509-
IStreamListener::kKeyResumeAtPTS,
510-
(int64_t *)&resumeAtPTS)) {
511-
int64_t resumeAtMediaTimeUs =
512-
mProgram->convertPTSToTimestamp(resumeAtPTS);
537+
mQueue->clear(clearFormat);
513538

514-
extra->setInt64("resume-at-mediatimeUs", resumeAtMediaTimeUs);
515-
}
539+
if (type & DISCONTINUITY_TIME) {
540+
uint64_t resumeAtPTS;
541+
if (extra != NULL
542+
&& extra->findInt64(
543+
IStreamListener::kKeyResumeAtPTS,
544+
(int64_t *)&resumeAtPTS)) {
545+
int64_t resumeAtMediaTimeUs =
546+
mProgram->convertPTSToTimestamp(resumeAtPTS);
516547

517-
if (mSource != NULL) {
518-
mSource->queueDiscontinuity(type, extra);
519-
}
520-
break;
548+
extra->setInt64("resume-at-mediatimeUs", resumeAtMediaTimeUs);
521549
}
550+
}
522551

523-
default:
524-
TRESPASS();
525-
break;
552+
if (mSource != NULL) {
553+
mSource->queueDiscontinuity(type, extra);
526554
}
527555
}
528556

@@ -764,20 +792,15 @@ sp<MediaSource> ATSParser::Stream::getSource(SourceType type) {
764792
switch (type) {
765793
case VIDEO:
766794
{
767-
if (mStreamType == STREAMTYPE_H264
768-
|| mStreamType == STREAMTYPE_MPEG1_VIDEO
769-
|| mStreamType == STREAMTYPE_MPEG2_VIDEO
770-
|| mStreamType == STREAMTYPE_MPEG4_VIDEO) {
795+
if (isVideo()) {
771796
return mSource;
772797
}
773798
break;
774799
}
775800

776801
case AUDIO:
777802
{
778-
if (mStreamType == STREAMTYPE_MPEG1_AUDIO
779-
|| mStreamType == STREAMTYPE_MPEG2_AUDIO
780-
|| mStreamType == STREAMTYPE_MPEG2_AUDIO_ATDS) {
803+
if (isAudio()) {
781804
return mSource;
782805
}
783806
break;

media/libstagefright/mpeg2ts/ATSParser.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,18 @@ struct MediaSource;
3333

3434
struct ATSParser : public RefBase {
3535
enum DiscontinuityType {
36-
DISCONTINUITY_NONE,
37-
DISCONTINUITY_SEEK,
38-
DISCONTINUITY_FORMATCHANGE
36+
DISCONTINUITY_NONE = 0,
37+
DISCONTINUITY_TIME = 1,
38+
DISCONTINUITY_AUDIO_FORMAT = 2,
39+
DISCONTINUITY_VIDEO_FORMAT = 4,
40+
41+
DISCONTINUITY_SEEK = DISCONTINUITY_TIME,
42+
43+
// For legacy reasons this also implies a time discontinuity.
44+
DISCONTINUITY_FORMATCHANGE =
45+
DISCONTINUITY_AUDIO_FORMAT
46+
| DISCONTINUITY_VIDEO_FORMAT
47+
| DISCONTINUITY_TIME,
3948
};
4049

4150
enum Flags {
@@ -71,7 +80,7 @@ struct ATSParser : public RefBase {
7180
STREAMTYPE_MPEG2_VIDEO = 0x02,
7281
STREAMTYPE_MPEG1_AUDIO = 0x03,
7382
STREAMTYPE_MPEG2_AUDIO = 0x04,
74-
STREAMTYPE_MPEG2_AUDIO_ATDS = 0x0f,
83+
STREAMTYPE_MPEG2_AUDIO_ADTS = 0x0f,
7584
STREAMTYPE_MPEG4_VIDEO = 0x10,
7685
STREAMTYPE_H264 = 0x1b,
7786
};

media/libstagefright/mpeg2ts/AnotherPacketSource.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,17 @@
2929
namespace android {
3030

3131
AnotherPacketSource::AnotherPacketSource(const sp<MetaData> &meta)
32-
: mFormat(meta),
32+
: mIsAudio(false),
33+
mFormat(meta),
3334
mEOSResult(OK) {
35+
const char *mime;
36+
CHECK(meta->findCString(kKeyMIMEType, &mime));
37+
38+
if (!strncasecmp("audio/", mime, 6)) {
39+
mIsAudio = true;
40+
} else {
41+
CHECK(!strncasecmp("video/", mime, 6));
42+
}
3443
}
3544

3645
void AnotherPacketSource::setFormat(const sp<MetaData> &meta) {
@@ -67,8 +76,7 @@ status_t AnotherPacketSource::dequeueAccessUnit(sp<ABuffer> *buffer) {
6776

6877
int32_t discontinuity;
6978
if ((*buffer)->meta()->findInt32("discontinuity", &discontinuity)) {
70-
71-
if (discontinuity == ATSParser::DISCONTINUITY_FORMATCHANGE) {
79+
if (wasFormatChange(discontinuity)) {
7280
mFormat.clear();
7381
}
7482

@@ -96,7 +104,7 @@ status_t AnotherPacketSource::read(
96104

97105
int32_t discontinuity;
98106
if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
99-
if (discontinuity == ATSParser::DISCONTINUITY_FORMATCHANGE) {
107+
if (wasFormatChange(discontinuity)) {
100108
mFormat.clear();
101109
}
102110

@@ -117,6 +125,15 @@ status_t AnotherPacketSource::read(
117125
return mEOSResult;
118126
}
119127

128+
bool AnotherPacketSource::wasFormatChange(
129+
int32_t discontinuityType) const {
130+
if (mIsAudio) {
131+
return (discontinuityType & ATSParser::DISCONTINUITY_AUDIO_FORMAT) != 0;
132+
}
133+
134+
return (discontinuityType & ATSParser::DISCONTINUITY_VIDEO_FORMAT) != 0;
135+
}
136+
120137
void AnotherPacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {
121138
int32_t damaged;
122139
if (buffer->meta()->findInt32("damaged", &damaged) && damaged) {

media/libstagefright/mpeg2ts/AnotherPacketSource.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,13 @@ struct AnotherPacketSource : public MediaSource {
6161
Mutex mLock;
6262
Condition mCondition;
6363

64+
bool mIsAudio;
6465
sp<MetaData> mFormat;
6566
List<sp<ABuffer> > mBuffers;
6667
status_t mEOSResult;
6768

69+
bool wasFormatChange(int32_t discontinuityType) const;
70+
6871
DISALLOW_EVIL_CONSTRUCTORS(AnotherPacketSource);
6972
};
7073

media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ MPEG2PSExtractor::Track::Track(
543543
case ATSParser::STREAMTYPE_H264:
544544
mode = ElementaryStreamQueue::H264;
545545
break;
546-
case ATSParser::STREAMTYPE_MPEG2_AUDIO_ATDS:
546+
case ATSParser::STREAMTYPE_MPEG2_AUDIO_ADTS:
547547
mode = ElementaryStreamQueue::AAC;
548548
break;
549549
case ATSParser::STREAMTYPE_MPEG1_AUDIO:

0 commit comments

Comments
 (0)