mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
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:
parent
6512e320fb
commit
53ec532a0e
6 changed files with 57 additions and 53 deletions
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,18 @@ 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()) {
|
||||||
throw new IllegalStateException("SeekMap cannot be seekable and have an unknown duration");
|
if (seekMap.getDurationUs() == C.TIME_UNSET) {
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue