summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/mpeg2ts/ATSParser.cpp
diff options
context:
space:
mode:
authorChong Zhang <chz@google.com>2015-03-02 23:42:38 -0800
committerChong Zhang <chz@google.com>2015-03-03 13:59:45 -0800
commit799c9682b3776a55d234396aee4a302437150c26 (patch)
tree2073aff9550b94bbe6770b3439bfa93ce7b5f6aa /media/libstagefright/mpeg2ts/ATSParser.cpp
parent9ee53a49860e91c2b012883eef09d669a7829e06 (diff)
downloadframeworks_av-799c9682b3776a55d234396aee4a302437150c26.zip
frameworks_av-799c9682b3776a55d234396aee4a302437150c26.tar.gz
frameworks_av-799c9682b3776a55d234396aee4a302437150c26.tar.bz2
handle mpeg2ts PTS wraparound
bug: 19587682 Change-Id: I805ed6aa330bda3dc0ec8bd3519fb1ffeaa81ca9
Diffstat (limited to 'media/libstagefright/mpeg2ts/ATSParser.cpp')
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.cpp22
1 files changed, 21 insertions, 1 deletions
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 482ccff..934e2e5 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -92,8 +92,10 @@ private:
KeyedVector<unsigned, sp<Stream> > mStreams;
bool mFirstPTSValid;
uint64_t mFirstPTS;
+ int64_t mLastRecoveredPTS;
status_t parseProgramMap(ABitReader *br);
+ int64_t recoverPTS(uint64_t PTS_33bit);
DISALLOW_EVIL_CONSTRUCTORS(Program);
};
@@ -182,7 +184,8 @@ ATSParser::Program::Program(
mProgramNumber(programNumber),
mProgramMapPID(programMapPID),
mFirstPTSValid(false),
- mFirstPTS(0) {
+ mFirstPTS(0),
+ mLastRecoveredPTS(0) {
ALOGV("new program number %u", programNumber);
}
@@ -425,6 +428,21 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
return OK;
}
+int64_t ATSParser::Program::recoverPTS(uint64_t PTS_33bit) {
+ // We only have the lower 33-bit of the PTS. It could overflow within a
+ // reasonable amount of time. To handle the wrap-around, use fancy math
+ // to get an extended PTS that is within [-0xffffffff, 0xffffffff]
+ // of the latest recovered PTS.
+ mLastRecoveredPTS = static_cast<int64_t>(
+ ((mLastRecoveredPTS - PTS_33bit + 0x100000000ll)
+ & 0xfffffffe00000000ull) | PTS_33bit);
+
+ // We start from 0, but recovered PTS could be slightly below 0.
+ // Clamp it to 0 as rest of the pipeline doesn't take negative pts.
+ // (eg. video is read first and starts at 0, but audio starts at 0xfffffff0)
+ return mLastRecoveredPTS < 0ll ? 0ll : mLastRecoveredPTS;
+}
+
sp<MediaSource> ATSParser::Program::getSource(SourceType type) {
size_t index = (type == AUDIO) ? 0 : 0;
@@ -455,6 +473,8 @@ bool ATSParser::Program::hasSource(SourceType type) const {
}
int64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) {
+ PTS = recoverPTS(PTS);
+
if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) {
if (!mFirstPTSValid) {
mFirstPTSValid = true;