summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/libstagefright/frameworks/av/media/libstagefright/SampleIterator.cpp13
-rw-r--r--media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp46
-rw-r--r--media/libstagefright/frameworks/av/media/libstagefright/include/SampleTable.h4
3 files changed, 49 insertions, 14 deletions
diff --git a/media/libstagefright/frameworks/av/media/libstagefright/SampleIterator.cpp b/media/libstagefright/frameworks/av/media/libstagefright/SampleIterator.cpp
index 37bb2b7a5..f1c797c9a 100644
--- a/media/libstagefright/frameworks/av/media/libstagefright/SampleIterator.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/SampleIterator.cpp
@@ -321,7 +321,18 @@ status_t SampleIterator::findSampleTime(
*time = mTTSSampleTime + mTTSDuration * (sampleIndex - mTTSSampleIndex);
- *time += mTable->getCompositionTimeOffset(sampleIndex);
+ int32_t offset = mTable->getCompositionTimeOffset(sampleIndex);
+ if ((offset < 0 && *time < (offset == INT32_MIN ?
+ INT32_MAX : uint32_t(-offset))) ||
+ (offset > 0 && *time > UINT32_MAX - offset)) {
+ ALOGE("%u + %d would overflow", *time, offset);
+ return ERROR_OUT_OF_RANGE;
+ }
+ if (offset > 0) {
+ *time += offset;
+ } else {
+ *time -= (offset == INT32_MIN ? INT32_MAX : (-offset));
+ }
return OK;
}
diff --git a/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp b/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp
index bbb2227e7..bc991e8e1 100644
--- a/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp
@@ -52,14 +52,14 @@ struct SampleTable::CompositionDeltaLookup {
CompositionDeltaLookup();
void setEntries(
- const uint32_t *deltaEntries, size_t numDeltaEntries);
+ const int32_t *deltaEntries, size_t numDeltaEntries);
- uint32_t getCompositionTimeOffset(uint32_t sampleIndex);
+ int32_t getCompositionTimeOffset(uint32_t sampleIndex);
private:
Mutex mLock;
- const uint32_t *mDeltaEntries;
+ const int32_t *mDeltaEntries;
size_t mNumDeltaEntries;
size_t mCurrentDeltaEntry;
@@ -76,7 +76,7 @@ SampleTable::CompositionDeltaLookup::CompositionDeltaLookup()
}
void SampleTable::CompositionDeltaLookup::setEntries(
- const uint32_t *deltaEntries, size_t numDeltaEntries) {
+ const int32_t *deltaEntries, size_t numDeltaEntries) {
Mutex::Autolock autolock(mLock);
mDeltaEntries = deltaEntries;
@@ -85,7 +85,7 @@ void SampleTable::CompositionDeltaLookup::setEntries(
mCurrentEntrySampleIndex = 0;
}
-uint32_t SampleTable::CompositionDeltaLookup::getCompositionTimeOffset(
+int32_t SampleTable::CompositionDeltaLookup::getCompositionTimeOffset(
uint32_t sampleIndex) {
Mutex::Autolock autolock(mLock);
@@ -381,6 +381,10 @@ status_t SampleTable::setTimeToSampleParams(
return OK;
}
+// NOTE: per 14996-12, version 0 ctts contains unsigned values, while version 1
+// contains signed values, however some software creates version 0 files that
+// contain signed values, so we're always treating the values as signed,
+// regardless of version.
status_t SampleTable::setCompositionTimeToSampleParams(
off64_t data_offset, size_t data_size) {
ALOGV("There are reordered frames present.");
@@ -398,8 +402,12 @@ status_t SampleTable::setCompositionTimeToSampleParams(
uint32_t numEntries = U32_AT(&header[4]);
- if (U32_AT(header) != 0 && numEntries) {
- // Expected version = 0, flags = 0.
+ uint32_t flags = U32_AT(header);
+ uint32_t version = flags >> 24;
+ flags &= 0xffffff;
+
+ if ((version != 0 && version != 1) || flags != 0) {
+ // Expected version = 0 or 1, flags = 0.
return ERROR_MALFORMED;
}
@@ -408,7 +416,7 @@ status_t SampleTable::setCompositionTimeToSampleParams(
}
mNumCompositionTimeDeltaEntries = numEntries;
- mCompositionTimeDeltaEntries = new (mozilla::fallible) uint32_t[2 * numEntries];
+ mCompositionTimeDeltaEntries = new (mozilla::fallible) int32_t[2 * numEntries];
if (!mCompositionTimeDeltaEntries) {
return ERROR_BUFFER_TOO_SMALL;
}
@@ -801,12 +809,28 @@ status_t SampleTable::buildSampleEntriesTable() {
mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;
- uint32_t compTimeDelta =
+ int32_t compTimeDelta =
mCompositionDeltaLookup->getCompositionTimeOffset(
sampleIndex);
+ if ((compTimeDelta < 0 && sampleTime <
+ (compTimeDelta == INT32_MIN ?
+ INT32_MAX : uint32_t(-compTimeDelta)))
+ || (compTimeDelta > 0 &&
+ sampleTime > UINT32_MAX - compTimeDelta)) {
+ ALOGE("%u + %d would overflow, clamping",
+ sampleTime, compTimeDelta);
+ if (compTimeDelta < 0) {
+ sampleTime = 0;
+ } else {
+ sampleTime = UINT32_MAX;
+ }
+ compTimeDelta = 0;
+ }
+
mSampleTimeEntries[sampleIndex].mCompositionTime =
- sampleTime + compTimeDelta;
+ compTimeDelta > 0 ? sampleTime + compTimeDelta:
+ sampleTime - (-compTimeDelta);
}
++sampleIndex;
@@ -1136,7 +1160,7 @@ status_t SampleTable::getMetaDataForSample(
return OK;
}
-uint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) {
+int32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) {
return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex);
}
diff --git a/media/libstagefright/frameworks/av/media/libstagefright/include/SampleTable.h b/media/libstagefright/frameworks/av/media/libstagefright/include/SampleTable.h
index e115c92bb..c235f281e 100644
--- a/media/libstagefright/frameworks/av/media/libstagefright/include/SampleTable.h
+++ b/media/libstagefright/frameworks/av/media/libstagefright/include/SampleTable.h
@@ -134,7 +134,7 @@ private:
};
SampleTimeEntry *mSampleTimeEntries;
- uint32_t *mCompositionTimeDeltaEntries;
+ int32_t *mCompositionTimeDeltaEntries;
size_t mNumCompositionTimeDeltaEntries;
CompositionDeltaLookup *mCompositionDeltaLookup;
@@ -171,7 +171,7 @@ private:
friend struct SampleIterator;
status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size);
- uint32_t getCompositionTimeOffset(uint32_t sampleIndex);
+ int32_t getCompositionTimeOffset(uint32_t sampleIndex);
static int CompareIncreasingTime(const void *, const void *);