summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/mpeg2ts
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/mpeg2ts')
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.cpp34
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.h1
-rw-r--r--media/libstagefright/mpeg2ts/AnotherPacketSource.cpp36
-rw-r--r--media/libstagefright/mpeg2ts/AnotherPacketSource.h1
-rw-r--r--media/libstagefright/mpeg2ts/ESQueue.cpp9
-rw-r--r--media/libstagefright/mpeg2ts/ESQueue.h1
-rw-r--r--media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp14
7 files changed, 80 insertions, 16 deletions
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index bcaab9f..7c9b83a 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -49,6 +49,8 @@ struct ATSParser::Program : public RefBase {
unsigned pid, unsigned payload_unit_start_indicator,
ABitReader *br);
+ void signalDiscontinuity();
+
sp<MediaSource> getSource(SourceType type);
private:
@@ -67,6 +69,8 @@ struct ATSParser::Stream : public RefBase {
unsigned payload_unit_start_indicator,
ABitReader *br);
+ void signalDiscontinuity();
+
sp<MediaSource> getSource(SourceType type);
protected:
@@ -124,6 +128,12 @@ bool ATSParser::Program::parsePID(
return true;
}
+void ATSParser::Program::signalDiscontinuity() {
+ for (size_t i = 0; i < mStreams.size(); ++i) {
+ mStreams.editValueAt(i)->signalDiscontinuity();
+ }
+}
+
void ATSParser::Program::parseProgramMap(ABitReader *br) {
unsigned table_id = br->getBits(8);
LOGV(" table_id = %u", table_id);
@@ -271,6 +281,19 @@ void ATSParser::Stream::parse(
mBuffer->setRange(0, mBuffer->size() + payloadSizeBits / 8);
}
+void ATSParser::Stream::signalDiscontinuity() {
+ LOGV("Stream discontinuity");
+ mPayloadStarted = false;
+ mBuffer->setRange(0, 0);
+
+ mQueue.clear();
+
+ if (mStreamType == 0x1b && mSource != NULL) {
+ // Don't signal discontinuities on audio streams.
+ mSource->queueDiscontinuity();
+ }
+}
+
void ATSParser::Stream::parsePES(ABitReader *br) {
unsigned packet_startcode_prefix = br->getBits(24);
@@ -459,7 +482,10 @@ void ATSParser::Stream::onPayloadData(
mSource = new AnotherPacketSource(meta);
mSource->queueAccessUnit(accessUnit);
}
- } else {
+ } 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.
mSource->queueAccessUnit(accessUnit);
}
}
@@ -489,6 +515,12 @@ void ATSParser::feedTSPacket(const void *data, size_t size) {
parseTS(&br);
}
+void ATSParser::signalDiscontinuity() {
+ for (size_t i = 0; i < mPrograms.size(); ++i) {
+ mPrograms.editItemAt(i)->signalDiscontinuity();
+ }
+}
+
void ATSParser::parseProgramAssociationTable(ABitReader *br) {
unsigned table_id = br->getBits(8);
LOGV(" table_id = %u", table_id);
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 1e22e7b..9ec6d7b 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -33,6 +33,7 @@ struct ATSParser : public RefBase {
ATSParser();
void feedTSPacket(const void *data, size_t size);
+ void signalDiscontinuity();
enum SourceType {
AVC_VIDEO,
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index 3d51177..3f76820 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -59,21 +59,26 @@ status_t AnotherPacketSource::read(
if (!mBuffers.empty()) {
const sp<ABuffer> buffer = *mBuffers.begin();
+ mBuffers.erase(mBuffers.begin());
- uint64_t timeUs;
- CHECK(buffer->meta()->findInt64(
- "time", (int64_t *)&timeUs));
-
- MediaBuffer *mediaBuffer = new MediaBuffer(buffer->size());
- mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
+ int32_t discontinuity;
+ if (buffer->meta()->findInt32("discontinuity", &discontinuity)
+ && discontinuity) {
+ return INFO_DISCONTINUITY;
+ } else {
+ uint64_t timeUs;
+ CHECK(buffer->meta()->findInt64(
+ "time", (int64_t *)&timeUs));
- // hexdump(buffer->data(), buffer->size());
+ MediaBuffer *mediaBuffer = new MediaBuffer(buffer->size());
+ mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
- memcpy(mediaBuffer->data(), buffer->data(), buffer->size());
- *out = mediaBuffer;
+ // hexdump(buffer->data(), buffer->size());
- mBuffers.erase(mBuffers.begin());
- return OK;
+ memcpy(mediaBuffer->data(), buffer->data(), buffer->size());
+ *out = mediaBuffer;
+ return OK;
+ }
}
return mEOSResult;
@@ -91,6 +96,15 @@ void AnotherPacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {
mCondition.signal();
}
+void AnotherPacketSource::queueDiscontinuity() {
+ sp<ABuffer> buffer = new ABuffer(0);
+ buffer->meta()->setInt32("discontinuity", true);
+
+ Mutex::Autolock autoLock(mLock);
+ mBuffers.push_back(buffer);
+ mCondition.signal();
+}
+
void AnotherPacketSource::signalEOS(status_t result) {
CHECK(result != OK);
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.h b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
index ce83d21..6b43c4e 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.h
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
@@ -40,6 +40,7 @@ struct AnotherPacketSource : public MediaSource {
bool hasBufferAvailable(status_t *finalResult);
void queueAccessUnit(const sp<ABuffer> &buffer);
+ void queueDiscontinuity();
void signalEOS(status_t result);
protected:
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index d87040b..4a75ee4 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -115,6 +115,11 @@ static status_t getNextNALUnit(
return OK;
}
+void ElementaryStreamQueue::clear() {
+ mBuffer->setRange(0, 0);
+ mFormat.clear();
+}
+
status_t ElementaryStreamQueue::appendData(
const void *data, size_t size, int64_t timeUs) {
if (mBuffer == NULL || mBuffer->size() == 0) {
@@ -147,7 +152,7 @@ status_t ElementaryStreamQueue::appendData(
if (mBuffer == NULL || neededSize > mBuffer->capacity()) {
neededSize = (neededSize + 65535) & ~65535;
- LOGI("resizing buffer to size %d", neededSize);
+ LOGV("resizing buffer to size %d", neededSize);
sp<ABuffer> buffer = new ABuffer(neededSize);
if (mBuffer != NULL) {
@@ -498,6 +503,8 @@ sp<MetaData> ElementaryStreamQueue::MakeAVCCodecSpecificData(
meta->setInt32(kKeyWidth, width);
meta->setInt32(kKeyHeight, height);
+ LOGI("found AVC codec config (%d x %d)", width, height);
+
return meta;
}
diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h
index d2e87f2..246c390 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.h
+++ b/media/libstagefright/mpeg2ts/ESQueue.h
@@ -35,6 +35,7 @@ struct ElementaryStreamQueue {
ElementaryStreamQueue(Mode mode);
status_t appendData(const void *data, size_t size, int64_t timeUs);
+ void clear();
sp<ABuffer> dequeueAccessUnit();
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index c5257bb..0d96bd1 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -165,18 +165,26 @@ void MPEG2TSExtractor::init() {
LOGI("haveAudio=%d, haveVideo=%d", haveAudio, haveVideo);
}
+static bool isDiscontinuity(const uint8_t *data, ssize_t size) {
+ return size == 188 && data[0] == 0x00;
+}
+
status_t MPEG2TSExtractor::feedMore() {
Mutex::Autolock autoLock(mLock);
uint8_t packet[kTSPacketSize];
ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize);
- if (n < (ssize_t)kTSPacketSize) {
+ if (isDiscontinuity(packet, n)) {
+ LOGI("XXX discontinuity detected");
+ mParser->signalDiscontinuity();
+ } else if (n < (ssize_t)kTSPacketSize) {
return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM;
+ } else {
+ mParser->feedTSPacket(packet, kTSPacketSize);
}
- mOffset += kTSPacketSize;
- mParser->feedTSPacket(packet, kTSPacketSize);
+ mOffset += n;
return OK;
}