summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/mpeg2ts
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2011-01-21 10:15:23 -0800
committerAndreas Huber <andih@google.com>2011-01-21 10:34:40 -0800
commitbc7f5b2e56107cfeaeeab13cf8979379e3c2f139 (patch)
treedffbfa1a0c661a0bd986d3ef8d80287cb0bcc513 /media/libstagefright/mpeg2ts
parentb408222bd9479c291874b607acae1425d6154fe7 (diff)
downloadframeworks_av-bc7f5b2e56107cfeaeeab13cf8979379e3c2f139.zip
frameworks_av-bc7f5b2e56107cfeaeeab13cf8979379e3c2f139.tar.gz
frameworks_av-bc7f5b2e56107cfeaeeab13cf8979379e3c2f139.tar.bz2
Some tweaks to HTTP live / nuplayer behaviour
- play audio-only streams again - workaround for malformed streams that switch PIDs across bandwidths - attempt to pick a different bandwidth stream if the previously chosen one appears to be malformed/unsupported. Change-Id: I426d0a40dc725aa242f619d4c9d048b69aca55c9 related-to-bug: 2368598
Diffstat (limited to 'media/libstagefright/mpeg2ts')
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.cpp85
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.h1
2 files changed, 72 insertions, 14 deletions
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index d8ab080..4335b99 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -75,6 +75,10 @@ private:
struct ATSParser::Stream : public RefBase {
Stream(Program *program, unsigned elementaryPID, unsigned streamType);
+ unsigned type() const { return mStreamType; }
+ unsigned pid() const { return mElementaryPID; }
+ void setPID(unsigned pid) { mElementaryPID = pid; }
+
void parse(
unsigned payload_unit_start_indicator,
ABitReader *br);
@@ -95,6 +99,7 @@ private:
sp<ABuffer> mBuffer;
sp<AnotherPacketSource> mSource;
bool mPayloadStarted;
+ DiscontinuityType mPendingDiscontinuity;
ElementaryStreamQueue mQueue;
@@ -107,6 +112,8 @@ private:
void extractAACFrames(const sp<ABuffer> &buffer);
+ void deferDiscontinuity(DiscontinuityType type);
+
DISALLOW_EVIL_CONSTRUCTORS(Stream);
};
@@ -155,6 +162,11 @@ void ATSParser::Program::signalEOS(status_t finalResult) {
}
}
+struct StreamInfo {
+ unsigned mType;
+ unsigned mPID;
+};
+
void ATSParser::Program::parseProgramMap(ABitReader *br) {
unsigned table_id = br->getBits(8);
LOGV(" table_id = %u", table_id);
@@ -188,6 +200,8 @@ void ATSParser::Program::parseProgramMap(ABitReader *br) {
br->skipBits(program_info_length * 8); // skip descriptors
+ Vector<StreamInfo> infos;
+
// infoBytesRemaining is the number of bytes that make up the
// variable length section of ES_infos. It does not include the
// final CRC.
@@ -231,24 +245,48 @@ void ATSParser::Program::parseProgramMap(ABitReader *br) {
CHECK_EQ(info_bytes_remaining, 0u);
#endif
- ssize_t index = mStreams.indexOfKey(elementaryPID);
-#if 0 // XXX revisit
- CHECK_LT(index, 0);
- mStreams.add(elementaryPID,
- new Stream(this, elementaryPID, streamType));
-#else
- if (index < 0) {
- mStreams.add(elementaryPID,
- new Stream(this, elementaryPID, streamType));
- }
-#endif
+ StreamInfo info;
+ info.mType = streamType;
+ info.mPID = elementaryPID;
+ infos.push(info);
infoBytesRemaining -= 5 + ES_info_length;
}
CHECK_EQ(infoBytesRemaining, 0u);
-
MY_LOGV(" CRC = 0x%08x", br->getBits(32));
+
+ bool PIDsChanged = false;
+ for (size_t i = 0; i < infos.size(); ++i) {
+ StreamInfo &info = infos.editItemAt(i);
+
+ ssize_t index = mStreams.indexOfKey(info.mPID);
+
+ if (index >= 0 && mStreams.editValueAt(index)->type() != info.mType) {
+ LOGI("uh oh. stream PIDs have changed.");
+ PIDsChanged = true;
+ break;
+ }
+ }
+
+ if (PIDsChanged) {
+ mStreams.clear();
+ }
+
+ for (size_t i = 0; i < infos.size(); ++i) {
+ StreamInfo &info = infos.editItemAt(i);
+
+ ssize_t index = mStreams.indexOfKey(info.mPID);
+
+ if (index < 0) {
+ sp<Stream> stream = new Stream(this, info.mPID, info.mType);
+ mStreams.add(info.mPID, stream);
+
+ if (PIDsChanged) {
+ stream->signalDiscontinuity(DISCONTINUITY_FORMATCHANGE);
+ }
+ }
+ }
}
sp<MediaSource> ATSParser::Program::getSource(SourceType type) {
@@ -290,6 +328,7 @@ ATSParser::Stream::Stream(
mStreamType(streamType),
mBuffer(new ABuffer(192 * 1024)),
mPayloadStarted(false),
+ mPendingDiscontinuity(DISCONTINUITY_NONE),
mQueue(streamType == 0x1b
? ElementaryStreamQueue::H264 : ElementaryStreamQueue::AAC) {
mBuffer->setRange(0, 0);
@@ -336,9 +375,13 @@ void ATSParser::Stream::signalDiscontinuity(DiscontinuityType type) {
{
mQueue.clear(true);
- if (mStreamType == 0x1b && mSource != NULL) {
+ if (mStreamType == 0x1b) {
// Don't signal discontinuities on audio streams.
- mSource->queueDiscontinuity(type);
+ if (mSource != NULL) {
+ mSource->queueDiscontinuity(type);
+ } else {
+ deferDiscontinuity(type);
+ }
}
break;
}
@@ -352,6 +395,8 @@ void ATSParser::Stream::signalDiscontinuity(DiscontinuityType type) {
if (mSource != NULL) {
mSource->queueDiscontinuity(type);
+ } else {
+ deferDiscontinuity(type);
}
break;
}
@@ -362,6 +407,13 @@ void ATSParser::Stream::signalDiscontinuity(DiscontinuityType type) {
}
}
+void ATSParser::Stream::deferDiscontinuity(DiscontinuityType type) {
+ if (type > mPendingDiscontinuity) {
+ // Only upgrade discontinuities.
+ mPendingDiscontinuity = type;
+ }
+}
+
void ATSParser::Stream::signalEOS(status_t finalResult) {
if (mSource != NULL) {
mSource->signalEOS(finalResult);
@@ -558,6 +610,11 @@ void ATSParser::Stream::onPayloadData(
LOGV("created source!");
mSource = new AnotherPacketSource(meta);
+ if (mPendingDiscontinuity != DISCONTINUITY_NONE) {
+ mSource->queueDiscontinuity(mPendingDiscontinuity);
+ mPendingDiscontinuity = DISCONTINUITY_NONE;
+ }
+
mSource->queueAccessUnit(accessUnit);
}
} else if (mQueue.getFormat() != NULL) {
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index fe31981..ec3be84 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -33,6 +33,7 @@ struct MediaSource;
struct ATSParser : public RefBase {
enum DiscontinuityType {
+ DISCONTINUITY_NONE,
DISCONTINUITY_HTTPLIVE,
DISCONTINUITY_SEEK,
DISCONTINUITY_FORMATCHANGE