Add more SeekMap assertions, and "fix" MatroskaExtractor

In MatroskaExtractor, if the last cue time exceeds the duration
specified in the header, then we end up generating a negative
duration chunk as the last item in the SeekMap. We should probably
not do this, so drop it instead.

Note: Matroska does have a CueDuration element, but it's not used
in the one problematic file I've found.
PiperOrigin-RevId: 285738418
This commit is contained in:
olly 2019-12-16 11:17:11 +00:00 committed by Oliver Woodman
parent 6512e320fb
commit 53ec532a0e
6 changed files with 57 additions and 53 deletions

View file

@ -1635,6 +1635,16 @@ public class MatroskaExtractor implements Extractor {
sizes[cuePointsSize - 1] = sizes[cuePointsSize - 1] =
(int) (segmentContentPosition + segmentContentSize - offsets[cuePointsSize - 1]); (int) (segmentContentPosition + segmentContentSize - offsets[cuePointsSize - 1]);
durationsUs[cuePointsSize - 1] = durationUs - timesUs[cuePointsSize - 1]; durationsUs[cuePointsSize - 1] = durationUs - timesUs[cuePointsSize - 1];
long lastDurationUs = durationsUs[cuePointsSize - 1];
if (lastDurationUs <= 0) {
Log.w(TAG, "Discarding last cue point with unexpected duration: " + lastDurationUs);
sizes = Arrays.copyOf(sizes, sizes.length - 1);
offsets = Arrays.copyOf(offsets, offsets.length - 1);
durationsUs = Arrays.copyOf(durationsUs, durationsUs.length - 1);
timesUs = Arrays.copyOf(timesUs, timesUs.length - 1);
}
cueTimesUs = null; cueTimesUs = null;
cueClusterPositions = null; cueClusterPositions = null;
return new ChunkIndex(sizes, offsets, durationsUs, timesUs); return new ChunkIndex(sizes, offsets, durationsUs, timesUs);

View file

@ -1,6 +1,6 @@
seekMap: seekMap:
isSeekable = true isSeekable = true
duration = 1072000 duration = 1104000
getPosition(0) = [[timeUs=67000, position=5576]] getPosition(0) = [[timeUs=67000, position=5576]]
numberOfTracks = 2 numberOfTracks = 2
track 1: track 1:

View file

@ -1,6 +1,6 @@
seekMap: seekMap:
isSeekable = true isSeekable = true
duration = 1072000 duration = 1104000
getPosition(0) = [[timeUs=67000, position=5576]] getPosition(0) = [[timeUs=67000, position=5576]]
numberOfTracks = 2 numberOfTracks = 2
track 1: track 1:
@ -28,93 +28,85 @@ track 1:
initializationData: initializationData:
data = length 30, hash F6F3D010 data = length 30, hash F6F3D010
data = length 10, hash 7A0D0F2B data = length 10, hash 7A0D0F2B
total output bytes = 30995 total output bytes = 29422
sample count = 22 sample count = 20
sample 0: sample 0:
time = 334000
flags = 0
data = length 953, hash 7160C661
sample 1:
time = 300000
flags = 0
data = length 620, hash 7A7AE07C
sample 2:
time = 367000 time = 367000
flags = 0 flags = 0
data = length 405, hash 5CC7F4E7 data = length 405, hash 5CC7F4E7
sample 3: sample 1:
time = 500000 time = 500000
flags = 0 flags = 0
data = length 4852, hash 9DB6979D data = length 4852, hash 9DB6979D
sample 4: sample 2:
time = 467000 time = 467000
flags = 0 flags = 0
data = length 547, hash E31A6979 data = length 547, hash E31A6979
sample 5: sample 3:
time = 434000 time = 434000
flags = 0 flags = 0
data = length 570, hash FEC40D00 data = length 570, hash FEC40D00
sample 6: sample 4:
time = 634000 time = 634000
flags = 0 flags = 0
data = length 5525, hash 7C478F7E data = length 5525, hash 7C478F7E
sample 7: sample 5:
time = 567000 time = 567000
flags = 0 flags = 0
data = length 1082, hash DA07059A data = length 1082, hash DA07059A
sample 8: sample 6:
time = 534000 time = 534000
flags = 0 flags = 0
data = length 807, hash 93478E6B data = length 807, hash 93478E6B
sample 9: sample 7:
time = 600000 time = 600000
flags = 0 flags = 0
data = length 744, hash 9A8E6026 data = length 744, hash 9A8E6026
sample 10: sample 8:
time = 767000 time = 767000
flags = 0 flags = 0
data = length 4732, hash C73B23C0 data = length 4732, hash C73B23C0
sample 11: sample 9:
time = 700000 time = 700000
flags = 0 flags = 0
data = length 1004, hash 8A19A228 data = length 1004, hash 8A19A228
sample 12: sample 10:
time = 667000 time = 667000
flags = 0 flags = 0
data = length 794, hash 8126022C data = length 794, hash 8126022C
sample 13: sample 11:
time = 734000 time = 734000
flags = 0 flags = 0
data = length 645, hash F08300E5 data = length 645, hash F08300E5
sample 14: sample 12:
time = 900000 time = 900000
flags = 0 flags = 0
data = length 2684, hash 727FE378 data = length 2684, hash 727FE378
sample 15: sample 13:
time = 834000 time = 834000
flags = 0 flags = 0
data = length 787, hash 419A7821 data = length 787, hash 419A7821
sample 16: sample 14:
time = 800000 time = 800000
flags = 0 flags = 0
data = length 649, hash 5C159346 data = length 649, hash 5C159346
sample 17: sample 15:
time = 867000 time = 867000
flags = 0 flags = 0
data = length 509, hash F912D655 data = length 509, hash F912D655
sample 18: sample 16:
time = 1034000 time = 1034000
flags = 0 flags = 0
data = length 1226, hash 29815C21 data = length 1226, hash 29815C21
sample 19: sample 17:
time = 967000 time = 967000
flags = 0 flags = 0
data = length 898, hash D997AD0A data = length 898, hash D997AD0A
sample 20: sample 18:
time = 934000 time = 934000
flags = 0 flags = 0
data = length 476, hash A0423645 data = length 476, hash A0423645
sample 21: sample 19:
time = 1000000 time = 1000000
flags = 0 flags = 0
data = length 486, hash DDF32CBB data = length 486, hash DDF32CBB

View file

@ -1,6 +1,6 @@
seekMap: seekMap:
isSeekable = true isSeekable = true
duration = 1072000 duration = 1104000
getPosition(0) = [[timeUs=67000, position=5576]] getPosition(0) = [[timeUs=67000, position=5576]]
numberOfTracks = 2 numberOfTracks = 2
track 1: track 1:
@ -28,49 +28,41 @@ track 1:
initializationData: initializationData:
data = length 30, hash F6F3D010 data = length 30, hash F6F3D010
data = length 10, hash 7A0D0F2B data = length 10, hash 7A0D0F2B
total output bytes = 10158 total output bytes = 8360
sample count = 11 sample count = 9
sample 0: sample 0:
time = 700000
flags = 0
data = length 1004, hash 8A19A228
sample 1:
time = 667000
flags = 0
data = length 794, hash 8126022C
sample 2:
time = 734000 time = 734000
flags = 0 flags = 0
data = length 645, hash F08300E5 data = length 645, hash F08300E5
sample 3: sample 1:
time = 900000 time = 900000
flags = 0 flags = 0
data = length 2684, hash 727FE378 data = length 2684, hash 727FE378
sample 4: sample 2:
time = 834000 time = 834000
flags = 0 flags = 0
data = length 787, hash 419A7821 data = length 787, hash 419A7821
sample 5: sample 3:
time = 800000 time = 800000
flags = 0 flags = 0
data = length 649, hash 5C159346 data = length 649, hash 5C159346
sample 6: sample 4:
time = 867000 time = 867000
flags = 0 flags = 0
data = length 509, hash F912D655 data = length 509, hash F912D655
sample 7: sample 5:
time = 1034000 time = 1034000
flags = 0 flags = 0
data = length 1226, hash 29815C21 data = length 1226, hash 29815C21
sample 8: sample 6:
time = 967000 time = 967000
flags = 0 flags = 0
data = length 898, hash D997AD0A data = length 898, hash D997AD0A
sample 9: sample 7:
time = 934000 time = 934000
flags = 0 flags = 0
data = length 476, hash A0423645 data = length 476, hash A0423645
sample 10: sample 8:
time = 1000000 time = 1000000
flags = 0 flags = 0
data = length 486, hash DDF32CBB data = length 486, hash DDF32CBB

View file

@ -1,6 +1,6 @@
seekMap: seekMap:
isSeekable = true isSeekable = true
duration = 1072000 duration = 1104000
getPosition(0) = [[timeUs=67000, position=5576]] getPosition(0) = [[timeUs=67000, position=5576]]
numberOfTracks = 2 numberOfTracks = 2
track 1: track 1:

View file

@ -70,9 +70,19 @@ public final class FakeExtractorOutput implements ExtractorOutput, Dumper.Dumpab
@Override @Override
public void seekMap(SeekMap seekMap) { public void seekMap(SeekMap seekMap) {
if (seekMap.isSeekable() && seekMap.getDurationUs() == C.TIME_UNSET) { if (seekMap.isSeekable()) {
if (seekMap.getDurationUs() == C.TIME_UNSET) {
throw new IllegalStateException("SeekMap cannot be seekable and have an unknown duration"); throw new IllegalStateException("SeekMap cannot be seekable and have an unknown duration");
} }
SeekMap.SeekPoints seekPoints = seekMap.getSeekPoints(0);
if (!seekPoints.first.equals(seekPoints.second)) {
throw new IllegalStateException("SeekMap defines two seek points for t=0");
}
seekPoints = seekMap.getSeekPoints(seekMap.getDurationUs());
if (!seekPoints.first.equals(seekPoints.second)) {
throw new IllegalStateException("SeekMap defines two seek points for t=durationUs");
}
}
this.seekMap = seekMap; this.seekMap = seekMap;
} }