diff options
author | Andreas Huber <andih@google.com> | 2011-08-31 16:44:49 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-08-31 16:44:49 -0700 |
commit | aec548b979f3d64712e8aa84cffdc4b7f094a798 (patch) | |
tree | db85875efd52fd8893b9a033b5bb529d79ccdeba /media | |
parent | ef96bbce63da03bc0f0ad86174567cfdd5990c1b (diff) | |
parent | 06528d7f18ad01377357d337eaa3e875a242bd2d (diff) | |
download | frameworks_av-aec548b979f3d64712e8aa84cffdc4b7f094a798.zip frameworks_av-aec548b979f3d64712e8aa84cffdc4b7f094a798.tar.gz frameworks_av-aec548b979f3d64712e8aa84cffdc4b7f094a798.tar.bz2 |
Merge "I have one HLS stream that switches stream PIDs from one bandwidth to the next"
Diffstat (limited to 'media')
-rw-r--r-- | media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp | 9 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/StreamingSource.cpp | 10 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/ATSParser.cpp | 98 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/ATSParser.h | 6 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp | 5 |
5 files changed, 101 insertions, 27 deletions
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp index 0251baf..605d056 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp @@ -124,7 +124,14 @@ bool NuPlayer::HTTPLiveSource::feedMoreTSData() { : ATSParser::DISCONTINUITY_FORMATCHANGE, extra); } else { - mTSParser->feedTSPacket(buffer, sizeof(buffer)); + status_t err = mTSParser->feedTSPacket(buffer, sizeof(buffer)); + + if (err != OK) { + LOGE("TS Parser returned error %d", err); + mTSParser->signalEOS(err); + mEOS = true; + break; + } } mOffset += n; diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp index f41e9d2..a741987 100644 --- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp +++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp @@ -86,7 +86,15 @@ bool NuPlayer::StreamingSource::feedMoreTSData() { : ATSParser::DISCONTINUITY_FORMATCHANGE, extra); } else { - mTSParser->feedTSPacket(buffer, sizeof(buffer)); + status_t err = mTSParser->feedTSPacket(buffer, sizeof(buffer)); + + if (err != OK) { + LOGE("TS Parser returned error %d", err); + + mTSParser->signalEOS(err); + mEOS = true; + break; + } } } } diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index 0b7dc3d..017d01c 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -48,7 +48,7 @@ struct ATSParser::Program : public RefBase { bool parsePID( unsigned pid, unsigned payload_unit_start_indicator, - ABitReader *br); + ABitReader *br, status_t *err); void signalDiscontinuity( DiscontinuityType type, const sp<AMessage> &extra); @@ -77,7 +77,7 @@ private: bool mFirstPTSValid; uint64_t mFirstPTS; - void parseProgramMap(ABitReader *br); + status_t parseProgramMap(ABitReader *br); DISALLOW_EVIL_CONSTRUCTORS(Program); }; @@ -140,14 +140,17 @@ ATSParser::Program::Program( bool ATSParser::Program::parsePID( unsigned pid, unsigned payload_unit_start_indicator, - ABitReader *br) { + ABitReader *br, status_t *err) { + *err = OK; + if (pid == mProgramMapPID) { if (payload_unit_start_indicator) { unsigned skip = br->getBits(8); br->skipBits(skip * 8); } - parseProgramMap(br); + *err = parseProgramMap(br); + return true; } @@ -180,7 +183,7 @@ struct StreamInfo { unsigned mPID; }; -void ATSParser::Program::parseProgramMap(ABitReader *br) { +status_t ATSParser::Program::parseProgramMap(ABitReader *br) { unsigned table_id = br->getBits(8); LOGV(" table_id = %u", table_id); CHECK_EQ(table_id, 0x02u); @@ -283,7 +286,60 @@ void ATSParser::Program::parseProgramMap(ABitReader *br) { } if (PIDsChanged) { - mStreams.clear(); +#if 0 + LOGI("before:"); + for (size_t i = 0; i < mStreams.size(); ++i) { + sp<Stream> stream = mStreams.editValueAt(i); + + LOGI("PID 0x%08x => type 0x%02x", stream->pid(), stream->type()); + } + + LOGI("after:"); + for (size_t i = 0; i < infos.size(); ++i) { + StreamInfo &info = infos.editItemAt(i); + + LOGI("PID 0x%08x => type 0x%02x", info.mPID, info.mType); + } +#endif + + // The only case we can recover from is if we have two streams + // and they switched PIDs. + + bool success = false; + + if (mStreams.size() == 2 && infos.size() == 2) { + const StreamInfo &info1 = infos.itemAt(0); + const StreamInfo &info2 = infos.itemAt(1); + + sp<Stream> s1 = mStreams.editValueAt(0); + sp<Stream> s2 = mStreams.editValueAt(1); + + bool caseA = + info1.mPID == s1->pid() && info1.mType == s2->type() + && info2.mPID == s2->pid() && info2.mType == s1->type(); + + bool caseB = + info1.mPID == s2->pid() && info1.mType == s1->type() + && info2.mPID == s1->pid() && info2.mType == s2->type(); + + if (caseA || caseB) { + unsigned pid1 = s1->pid(); + unsigned pid2 = s2->pid(); + s1->setPID(pid2); + s2->setPID(pid1); + + mStreams.clear(); + mStreams.add(s1->pid(), s1); + mStreams.add(s2->pid(), s2); + + success = true; + } + } + + if (!success) { + LOGI("Stream PIDs changed and we cannot recover."); + return ERROR_MALFORMED; + } } for (size_t i = 0; i < infos.size(); ++i) { @@ -294,13 +350,10 @@ void ATSParser::Program::parseProgramMap(ABitReader *br) { if (index < 0) { sp<Stream> stream = new Stream(this, info.mPID, info.mType); mStreams.add(info.mPID, stream); - - if (PIDsChanged) { - sp<AMessage> extra; - stream->signalDiscontinuity(DISCONTINUITY_FORMATCHANGE, extra); - } } } + + return OK; } sp<MediaSource> ATSParser::Program::getSource(SourceType type) { @@ -724,11 +777,11 @@ ATSParser::ATSParser(uint32_t flags) ATSParser::~ATSParser() { } -void ATSParser::feedTSPacket(const void *data, size_t size) { +status_t ATSParser::feedTSPacket(const void *data, size_t size) { CHECK_EQ(size, kTSPacketSize); ABitReader br((const uint8_t *)data, kTSPacketSize); - parseTS(&br); + return parseTS(&br); } void ATSParser::signalDiscontinuity( @@ -806,7 +859,7 @@ void ATSParser::parseProgramAssociationTable(ABitReader *br) { MY_LOGV(" CRC = 0x%08x", br->getBits(32)); } -void ATSParser::parsePID( +status_t ATSParser::parsePID( ABitReader *br, unsigned PID, unsigned payload_unit_start_indicator) { if (PID == 0) { @@ -815,13 +868,18 @@ void ATSParser::parsePID( br->skipBits(skip * 8); } parseProgramAssociationTable(br); - return; + return OK; } bool handled = false; for (size_t i = 0; i < mPrograms.size(); ++i) { + status_t err; if (mPrograms.editItemAt(i)->parsePID( - PID, payload_unit_start_indicator, br)) { + PID, payload_unit_start_indicator, br, &err)) { + if (err != OK) { + return err; + } + handled = true; break; } @@ -830,6 +888,8 @@ void ATSParser::parsePID( if (!handled) { LOGV("PID 0x%04x not handled.", PID); } + + return OK; } void ATSParser::parseAdaptationField(ABitReader *br) { @@ -839,7 +899,7 @@ void ATSParser::parseAdaptationField(ABitReader *br) { } } -void ATSParser::parseTS(ABitReader *br) { +status_t ATSParser::parseTS(ABitReader *br) { LOGV("---"); unsigned sync_byte = br->getBits(8); @@ -870,8 +930,10 @@ void ATSParser::parseTS(ABitReader *br) { } if (adaptation_field_control == 1 || adaptation_field_control == 3) { - parsePID(br, PID, payload_unit_start_indicator); + return parsePID(br, PID, payload_unit_start_indicator); } + + return OK; } sp<MediaSource> ATSParser::getSource(SourceType type) { diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h index d12d998..388cb54 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.h +++ b/media/libstagefright/mpeg2ts/ATSParser.h @@ -49,7 +49,7 @@ struct ATSParser : public RefBase { ATSParser(uint32_t flags = 0); - void feedTSPacket(const void *data, size_t size); + status_t feedTSPacket(const void *data, size_t size); void signalDiscontinuity( DiscontinuityType type, const sp<AMessage> &extra); @@ -89,12 +89,12 @@ private: void parseProgramMap(ABitReader *br); void parsePES(ABitReader *br); - void parsePID( + status_t parsePID( ABitReader *br, unsigned PID, unsigned payload_unit_start_indicator); void parseAdaptationField(ABitReader *br); - void parseTS(ABitReader *br); + status_t parseTS(ABitReader *br); DISALLOW_EVIL_CONSTRUCTORS(ATSParser); }; diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp index 8250ad1..17cf45a 100644 --- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp +++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp @@ -210,13 +210,10 @@ status_t MPEG2TSExtractor::feedMore() { if (n < (ssize_t)kTSPacketSize) { return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM; - } else { - mParser->feedTSPacket(packet, kTSPacketSize); } mOffset += n; - - return OK; + return mParser->feedTSPacket(packet, kTSPacketSize); } void MPEG2TSExtractor::setLiveSession(const sp<LiveSession> &liveSession) { |