Fix the 0 sample count ctts entry bug

When the ctts contained an entry that had a 0-valued entry count, the
parser would miss every other entry, failing the final assertion.
The standard does not seem to prevent the value 0 in the sample_count
field, so we need to allow it.

Issue: #1326
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=117241945
This commit is contained in:
olly 2016-03-15 08:39:17 -07:00 committed by Oliver Woodman
parent f04e412a1c
commit 9777945ce2

View File

@ -152,14 +152,7 @@ import java.util.List;
int timestampOffset = 0;
if (ctts != null) {
ctts.setPosition(Atom.FULL_HEADER_SIZE);
remainingTimestampOffsetChanges = ctts.readUnsignedIntToInt() - 1;
remainingSamplesAtTimestampOffset = ctts.readUnsignedIntToInt();
// The BMFF spec (ISO 14496-12) states that sample offsets should be unsigned integers in
// version 0 ctts boxes, however some streams violate the spec and use signed integers
// instead. It's safe to always parse sample offsets as signed integers here, because
// unsigned integers will still be parsed correctly (unless their top bit is set, which
// is never true in practice because sample offsets are always small).
timestampOffset = ctts.readInt();
remainingTimestampOffsetChanges = ctts.readUnsignedIntToInt();
}
int nextSynchronizationSampleIndex = -1;
@ -180,6 +173,21 @@ import java.util.List;
long timestampTimeUnits = 0;
for (int i = 0; i < sampleCount; i++) {
// Add on the timestamp offset if ctts is present.
if (ctts != null) {
while (remainingSamplesAtTimestampOffset == 0 && remainingTimestampOffsetChanges > 0) {
remainingSamplesAtTimestampOffset = ctts.readUnsignedIntToInt();
// The BMFF spec (ISO 14496-12) states that sample offsets should be unsigned integers in
// version 0 ctts boxes, however some streams violate the spec and use signed integers
// instead. It's safe to always parse sample offsets as signed integers here, because
// unsigned integers will still be parsed correctly (unless their top bit is set, which is
// never true in practice because sample offsets are always small).
timestampOffset = ctts.readInt();
remainingTimestampOffsetChanges--;
}
remainingSamplesAtTimestampOffset--;
}
offsets[i] = offsetBytes;
sizes[i] = fixedSampleSize == 0 ? stsz.readUnsignedIntToInt() : fixedSampleSize;
if (sizes[i] > maximumSize) {
@ -206,17 +214,6 @@ import java.util.List;
remainingTimestampDeltaChanges--;
}
// Add on the timestamp offset if ctts is present.
if (ctts != null) {
remainingSamplesAtTimestampOffset--;
if (remainingSamplesAtTimestampOffset == 0 && remainingTimestampOffsetChanges > 0) {
remainingSamplesAtTimestampOffset = ctts.readUnsignedIntToInt();
// Read a signed offset even for version 0 ctts boxes (see comment above).
timestampOffset = ctts.readInt();
remainingTimestampOffsetChanges--;
}
}
// If we're at the last sample in this chunk, move to the next chunk.
remainingSamplesInChunk--;
if (remainingSamplesInChunk == 0) {