summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/mpeg2ts
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2011-08-31 16:29:05 -0700
committerAndreas Huber <andih@google.com>2011-08-31 16:29:05 -0700
commit06528d7f18ad01377357d337eaa3e875a242bd2d (patch)
treec08f45ba206b07b864f7a153f65fc739ae51fe1c /media/libstagefright/mpeg2ts
parent18ac5407da14dad9731f40ffc9a56bee73830019 (diff)
downloadframeworks_av-06528d7f18ad01377357d337eaa3e875a242bd2d.zip
frameworks_av-06528d7f18ad01377357d337eaa3e875a242bd2d.tar.gz
frameworks_av-06528d7f18ad01377357d337eaa3e875a242bd2d.tar.bz2
I have one HLS stream that switches stream PIDs from one bandwidth to the next
this change intends to support its very limited case and signals an error in all other cases of unexpected PID changes that we cannot recover from. Change-Id: Icbfdf9fe7461969e2a8781ed416f54d891dd789a
Diffstat (limited to 'media/libstagefright/mpeg2ts')
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.cpp98
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.h6
-rw-r--r--media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp5
3 files changed, 84 insertions, 25 deletions
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) {