summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2011-08-31 16:44:49 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-08-31 16:44:49 -0700
commitaec548b979f3d64712e8aa84cffdc4b7f094a798 (patch)
treedb85875efd52fd8893b9a033b5bb529d79ccdeba /media
parentef96bbce63da03bc0f0ad86174567cfdd5990c1b (diff)
parent06528d7f18ad01377357d337eaa3e875a242bd2d (diff)
downloadframeworks_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.cpp9
-rw-r--r--media/libmediaplayerservice/nuplayer/StreamingSource.cpp10
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.cpp98
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.h6
-rw-r--r--media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp5
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) {