mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-09 17:31:47 +09:00
Always treat composition time offsets as signed
Even for version 0 ctts atoms that technically should contain only unsigned values.
This commit is contained in:
parent
7d0bef1093
commit
a137fdb1c1
3 changed files with 49 additions and 14 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 *);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue