summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/mpeg2ts/ATSParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/mpeg2ts/ATSParser.cpp')
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.cpp130
1 files changed, 112 insertions, 18 deletions
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 7d4bc6e..5bbc2b4 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -44,7 +44,7 @@ namespace android {
static const size_t kTSPacketSize = 188;
struct ATSParser::Program : public RefBase {
- Program(ATSParser *parser, unsigned programMapPID);
+ Program(ATSParser *parser, unsigned programNumber, unsigned programMapPID);
bool parsePID(
unsigned pid, unsigned payload_unit_start_indicator,
@@ -63,8 +63,15 @@ struct ATSParser::Program : public RefBase {
return mFirstPTSValid;
}
+ unsigned number() const { return mProgramNumber; }
+
+ void updateProgramMapPID(unsigned programMapPID) {
+ mProgramMapPID = programMapPID;
+ }
+
private:
ATSParser *mParser;
+ unsigned mProgramNumber;
unsigned mProgramMapPID;
KeyedVector<unsigned, sp<Stream> > mStreams;
bool mFirstPTSValid;
@@ -107,7 +114,7 @@ private:
DiscontinuityType mPendingDiscontinuity;
sp<AMessage> mPendingDiscontinuityExtra;
- ElementaryStreamQueue mQueue;
+ ElementaryStreamQueue *mQueue;
void flush();
void parsePES(ABitReader *br);
@@ -126,11 +133,14 @@ private:
////////////////////////////////////////////////////////////////////////////////
-ATSParser::Program::Program(ATSParser *parser, unsigned programMapPID)
+ATSParser::Program::Program(
+ ATSParser *parser, unsigned programNumber, unsigned programMapPID)
: mParser(parser),
+ mProgramNumber(programNumber),
mProgramMapPID(programMapPID),
mFirstPTSValid(false),
mFirstPTS(0) {
+ LOGV("new program number %u", programNumber);
}
bool ATSParser::Program::parsePID(
@@ -299,7 +309,7 @@ void ATSParser::Program::parseProgramMap(ABitReader *br) {
}
sp<MediaSource> ATSParser::Program::getSource(SourceType type) {
- size_t index = (type == MPEG2ADTS_AUDIO) ? 0 : 0;
+ size_t index = (type == AUDIO) ? 0 : 0;
for (size_t i = 0; i < mStreams.size(); ++i) {
sp<MediaSource> source = mStreams.editValueAt(i)->getSource(type);
@@ -338,14 +348,43 @@ ATSParser::Stream::Stream(
mBuffer(new ABuffer(192 * 1024)),
mPayloadStarted(false),
mPendingDiscontinuity(DISCONTINUITY_NONE),
- mQueue(streamType == 0x1b
- ? ElementaryStreamQueue::H264 : ElementaryStreamQueue::AAC) {
+ mQueue(NULL) {
mBuffer->setRange(0, 0);
+ switch (mStreamType) {
+ case STREAMTYPE_H264:
+ mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::H264);
+ break;
+ case STREAMTYPE_MPEG2_AUDIO_ATDS:
+ mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::AAC);
+ break;
+ case STREAMTYPE_MPEG1_AUDIO:
+ case STREAMTYPE_MPEG2_AUDIO:
+ mQueue = new ElementaryStreamQueue(
+ ElementaryStreamQueue::MPEG_AUDIO);
+ break;
+
+ case STREAMTYPE_MPEG1_VIDEO:
+ case STREAMTYPE_MPEG2_VIDEO:
+ mQueue = new ElementaryStreamQueue(
+ ElementaryStreamQueue::MPEG_VIDEO);
+ break;
+
+ case STREAMTYPE_MPEG4_VIDEO:
+ mQueue = new ElementaryStreamQueue(
+ ElementaryStreamQueue::MPEG4_VIDEO);
+ break;
+
+ default:
+ break;
+ }
+
LOGV("new stream PID 0x%02x, type 0x%02x", elementaryPID, streamType);
}
ATSParser::Stream::~Stream() {
+ delete mQueue;
+ mQueue = NULL;
}
void ATSParser::Stream::parse(
@@ -397,7 +436,7 @@ void ATSParser::Stream::signalDiscontinuity(
{
bool isASeek = (type == DISCONTINUITY_SEEK);
- mQueue.clear(!isASeek);
+ mQueue->clear(!isASeek);
uint64_t resumeAtPTS;
if (extra != NULL
@@ -444,6 +483,12 @@ void ATSParser::Stream::parsePES(ABitReader *br) {
LOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
+ if (packet_startcode_prefix != 1) {
+ LOGV("Supposedly payload_unit_start=1 unit does not start "
+ "with startcode.");
+ return;
+ }
+
CHECK_EQ(packet_startcode_prefix, 0x000001u);
unsigned stream_id = br->getBits(8);
@@ -611,22 +656,28 @@ void ATSParser::Stream::onPayloadData(
const uint8_t *data, size_t size) {
LOGV("onPayloadData mStreamType=0x%02x", mStreamType);
+ if (mQueue == NULL) {
+ return;
+ }
+
CHECK(PTS_DTS_flags == 2 || PTS_DTS_flags == 3);
int64_t timeUs = mProgram->convertPTSToTimestamp(PTS);
- status_t err = mQueue.appendData(data, size, timeUs);
+ status_t err = mQueue->appendData(data, size, timeUs);
if (err != OK) {
return;
}
sp<ABuffer> accessUnit;
- while ((accessUnit = mQueue.dequeueAccessUnit()) != NULL) {
+ while ((accessUnit = mQueue->dequeueAccessUnit()) != NULL) {
if (mSource == NULL) {
- sp<MetaData> meta = mQueue.getFormat();
+ sp<MetaData> meta = mQueue->getFormat();
if (meta != NULL) {
- LOGV("created source!");
+ LOGV("Stream PID 0x%08x of type 0x%02x now has data.",
+ mElementaryPID, mStreamType);
+
mSource = new AnotherPacketSource(meta);
if (mPendingDiscontinuity != DISCONTINUITY_NONE) {
@@ -638,13 +689,13 @@ void ATSParser::Stream::onPayloadData(
mSource->queueAccessUnit(accessUnit);
}
- } else if (mQueue.getFormat() != NULL) {
+ } else if (mQueue->getFormat() != NULL) {
// After a discontinuity we invalidate the queue's format
// and won't enqueue any access units to the source until
// the queue has reestablished the new format.
if (mSource->getFormat() == NULL) {
- mSource->setFormat(mQueue.getFormat());
+ mSource->setFormat(mQueue->getFormat());
}
mSource->queueAccessUnit(accessUnit);
}
@@ -652,9 +703,30 @@ void ATSParser::Stream::onPayloadData(
}
sp<MediaSource> ATSParser::Stream::getSource(SourceType type) {
- if ((type == AVC_VIDEO && mStreamType == 0x1b)
- || (type == MPEG2ADTS_AUDIO && mStreamType == 0x0f)) {
- return mSource;
+ switch (type) {
+ case VIDEO:
+ {
+ if (mStreamType == STREAMTYPE_H264
+ || mStreamType == STREAMTYPE_MPEG1_VIDEO
+ || mStreamType == STREAMTYPE_MPEG2_VIDEO
+ || mStreamType == STREAMTYPE_MPEG4_VIDEO) {
+ return mSource;
+ }
+ break;
+ }
+
+ case AUDIO:
+ {
+ if (mStreamType == STREAMTYPE_MPEG1_AUDIO
+ || mStreamType == STREAMTYPE_MPEG2_AUDIO
+ || mStreamType == STREAMTYPE_MPEG2_AUDIO_ATDS) {
+ return mSource;
+ }
+ break;
+ }
+
+ default:
+ break;
}
return NULL;
@@ -729,7 +801,21 @@ void ATSParser::parseProgramAssociationTable(ABitReader *br) {
LOGV(" program_map_PID = 0x%04x", programMapPID);
- mPrograms.push(new Program(this, programMapPID));
+ bool found = false;
+ for (size_t index = 0; index < mPrograms.size(); ++index) {
+ const sp<Program> &program = mPrograms.itemAt(index);
+
+ if (program->number() == program_number) {
+ program->updateProgramMapPID(programMapPID);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ mPrograms.push(
+ new Program(this, program_number, programMapPID));
+ }
}
}
@@ -805,8 +891,16 @@ void ATSParser::parseTS(ABitReader *br) {
}
sp<MediaSource> ATSParser::getSource(SourceType type) {
+ int which = -1; // any
+
for (size_t i = 0; i < mPrograms.size(); ++i) {
- sp<MediaSource> source = mPrograms.editItemAt(i)->getSource(type);
+ const sp<Program> &program = mPrograms.editItemAt(i);
+
+ if (which >= 0 && (int)program->number() != which) {
+ continue;
+ }
+
+ sp<MediaSource> source = program->getSource(type);
if (source != NULL) {
return source;