summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2011-02-03 13:18:16 -0800
committerAndreas Huber <andih@google.com>2011-02-03 16:08:30 -0800
commit4931bb5259d10c1fa01e7405fb7aaef58a8ffb22 (patch)
treeaf9fd1764543c29813259fd482e71274a26844fc
parent856990b491d84b7ed4fefe337485c8997ba9dd02 (diff)
downloadframeworks_av-4931bb5259d10c1fa01e7405fb7aaef58a8ffb22.zip
frameworks_av-4931bb5259d10c1fa01e7405fb7aaef58a8ffb22.tar.gz
frameworks_av-4931bb5259d10c1fa01e7405fb7aaef58a8ffb22.tar.bz2
Make sure timestamps attached to encoded media are composition timestamps.
not decoding timestamps. Obviously there is no difference between them if the content in question does not involve frame reordering. Change-Id: Iac4d06cfeb8a136f735c1148e98cac340d3ef893 related-to-bug: 3398314
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp14
-rw-r--r--media/libstagefright/SampleIterator.cpp2
-rw-r--r--media/libstagefright/SampleTable.cpp73
-rw-r--r--media/libstagefright/include/SampleTable.h8
4 files changed, 97 insertions, 0 deletions
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index e6e98aa..108a1d1 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1074,6 +1074,20 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
break;
}
+ case FOURCC('c', 't', 't', 's'):
+ {
+ status_t err =
+ mLastTrack->sampleTable->setCompositionTimeToSampleParams(
+ data_offset, chunk_data_size);
+
+ if (err != OK) {
+ return err;
+ }
+
+ *offset += chunk_size;
+ break;
+ }
+
case FOURCC('s', 't', 's', 's'):
{
status_t err =
diff --git a/media/libstagefright/SampleIterator.cpp b/media/libstagefright/SampleIterator.cpp
index 062ab9b..c7b00b1 100644
--- a/media/libstagefright/SampleIterator.cpp
+++ b/media/libstagefright/SampleIterator.cpp
@@ -307,6 +307,8 @@ status_t SampleIterator::findSampleTime(
*time = mTTSSampleTime + mTTSDuration * (sampleIndex - mTTSSampleIndex);
+ *time += mTable->getCompositionTimeOffset(sampleIndex);
+
return OK;
}
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index a9163fc..423df70 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -53,6 +53,8 @@ SampleTable::SampleTable(const sp<DataSource> &source)
mNumSampleSizes(0),
mTimeToSampleCount(0),
mTimeToSample(NULL),
+ mCompositionTimeDeltaEntries(NULL),
+ mNumCompositionTimeDeltaEntries(0),
mSyncSampleOffset(-1),
mNumSyncSamples(0),
mSyncSamples(NULL),
@@ -68,6 +70,9 @@ SampleTable::~SampleTable() {
delete[] mSyncSamples;
mSyncSamples = NULL;
+ delete[] mCompositionTimeDeltaEntries;
+ mCompositionTimeDeltaEntries = NULL;
+
delete[] mTimeToSample;
mTimeToSample = NULL;
@@ -260,6 +265,51 @@ status_t SampleTable::setTimeToSampleParams(
return OK;
}
+status_t SampleTable::setCompositionTimeToSampleParams(
+ off64_t data_offset, size_t data_size) {
+ LOGI("There are reordered frames present.");
+
+ if (mCompositionTimeDeltaEntries != NULL || data_size < 8) {
+ return ERROR_MALFORMED;
+ }
+
+ uint8_t header[8];
+ if (mDataSource->readAt(
+ data_offset, header, sizeof(header))
+ < (ssize_t)sizeof(header)) {
+ return ERROR_IO;
+ }
+
+ if (U32_AT(header) != 0) {
+ // Expected version = 0, flags = 0.
+ return ERROR_MALFORMED;
+ }
+
+ size_t numEntries = U32_AT(&header[4]);
+
+ if (data_size != (numEntries + 1) * 8) {
+ return ERROR_MALFORMED;
+ }
+
+ mNumCompositionTimeDeltaEntries = numEntries;
+ mCompositionTimeDeltaEntries = new uint32_t[2 * numEntries];
+
+ if (mDataSource->readAt(
+ data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8)
+ < (ssize_t)numEntries * 8) {
+ delete[] mCompositionTimeDeltaEntries;
+ mCompositionTimeDeltaEntries = NULL;
+
+ return ERROR_IO;
+ }
+
+ for (size_t i = 0; i < 2 * numEntries; ++i) {
+ mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]);
+ }
+
+ return OK;
+}
+
status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) {
if (mSyncSampleOffset >= 0 || data_size < 8) {
return ERROR_MALFORMED;
@@ -333,6 +383,8 @@ uint32_t abs_difference(uint32_t time1, uint32_t time2) {
status_t SampleTable::findSampleAtTime(
uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
+ // XXX this currently uses decoding time, instead of composition time.
+
*sample_index = 0;
Mutex::Autolock autoLock(mLock);
@@ -607,5 +659,26 @@ status_t SampleTable::getMetaDataForSample(
return OK;
}
+uint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) const {
+ if (mCompositionTimeDeltaEntries == NULL) {
+ return 0;
+ }
+
+ uint32_t curSample = 0;
+ for (size_t i = 0; i < mNumCompositionTimeDeltaEntries; ++i) {
+ uint32_t sampleCount = mCompositionTimeDeltaEntries[2 * i];
+
+ if (sampleIndex < curSample + sampleCount) {
+ uint32_t sampleDelta = mCompositionTimeDeltaEntries[2 * i + 1];
+
+ return sampleDelta;
+ }
+
+ curSample += sampleCount;
+ }
+
+ return 0;
+}
+
} // namespace android
diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h
index c5e8136..2f95de9 100644
--- a/media/libstagefright/include/SampleTable.h
+++ b/media/libstagefright/include/SampleTable.h
@@ -46,6 +46,9 @@ public:
status_t setTimeToSampleParams(off64_t data_offset, size_t data_size);
+ status_t setCompositionTimeToSampleParams(
+ off64_t data_offset, size_t data_size);
+
status_t setSyncSampleParams(off64_t data_offset, size_t data_size);
////////////////////////////////////////////////////////////////////////////
@@ -104,6 +107,9 @@ private:
uint32_t mTimeToSampleCount;
uint32_t *mTimeToSample;
+ uint32_t *mCompositionTimeDeltaEntries;
+ size_t mNumCompositionTimeDeltaEntries;
+
off64_t mSyncSampleOffset;
uint32_t mNumSyncSamples;
uint32_t *mSyncSamples;
@@ -122,6 +128,8 @@ private:
status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size);
+ uint32_t getCompositionTimeOffset(uint32_t sampleIndex) const;
+
SampleTable(const SampleTable &);
SampleTable &operator=(const SampleTable &);
};