Fix handling of cues that exceed total duration in MatroskaExtractor

Adjusted logic to accurately calculate sizes and durations for the last valid cue point when cue timestamps are greater than the total duration.

Fixes the issue where the reported duration of the MKV file was greater than the total duration specified by the duration element. Verified this using `mkvinfo` and `mediainfo` tools.

PiperOrigin-RevId: 690961276
This commit is contained in:
rohks 2024-10-29 04:16:10 -07:00 committed by Copybara-Service
parent 51055d7e79
commit b1f2efd218
6 changed files with 80 additions and 56 deletions

View File

@ -1898,17 +1898,25 @@ public class MatroskaExtractor implements Extractor {
sizes[i] = (int) (offsets[i + 1] - offsets[i]); sizes[i] = (int) (offsets[i + 1] - offsets[i]);
durationsUs[i] = timesUs[i + 1] - timesUs[i]; durationsUs[i] = timesUs[i + 1] - timesUs[i];
} }
sizes[cuePointsSize - 1] =
(int) (segmentContentPosition + segmentContentSize - offsets[cuePointsSize - 1]);
durationsUs[cuePointsSize - 1] = durationUs - timesUs[cuePointsSize - 1];
long lastDurationUs = durationsUs[cuePointsSize - 1]; // Start from the last cue point and move backward until a valid duration is found.
if (lastDurationUs <= 0) { int lastValidIndex = cuePointsSize - 1;
Log.w(TAG, "Discarding last cue point with unexpected duration: " + lastDurationUs); while (lastValidIndex > 0 && timesUs[lastValidIndex] > durationUs) {
sizes = Arrays.copyOf(sizes, sizes.length - 1); lastValidIndex--;
offsets = Arrays.copyOf(offsets, offsets.length - 1); }
durationsUs = Arrays.copyOf(durationsUs, durationsUs.length - 1);
timesUs = Arrays.copyOf(timesUs, timesUs.length - 1); // Calculate sizes and durations for the last valid index
sizes[lastValidIndex] =
(int) (segmentContentPosition + segmentContentSize - offsets[lastValidIndex]);
durationsUs[lastValidIndex] = durationUs - timesUs[lastValidIndex];
// If the last valid index is not the last cue point, truncate the arrays
if (lastValidIndex < cuePointsSize - 1) {
Log.w(TAG, "Discarding trailing cue points with timestamps greater than total duration");
sizes = Arrays.copyOf(sizes, lastValidIndex + 1);
offsets = Arrays.copyOf(offsets, lastValidIndex + 1);
durationsUs = Arrays.copyOf(durationsUs, lastValidIndex + 1);
timesUs = Arrays.copyOf(timesUs, lastValidIndex + 1);
} }
return new ChunkIndex(sizes, offsets, durationsUs, timesUs); return new ChunkIndex(sizes, offsets, durationsUs, timesUs);

View File

@ -1,10 +1,10 @@
seekMap: seekMap:
isSeekable = true isSeekable = true
duration = 1104000 duration = 1072000
getPosition(0) = [[timeUs=67000, position=5576]] getPosition(0) = [[timeUs=67000, position=5576]]
getPosition(1) = [[timeUs=67000, position=5576]] getPosition(1) = [[timeUs=67000, position=5576]]
getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]] getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]]
getPosition(1104000) = [[timeUs=1035000, position=106570]] getPosition(1072000) = [[timeUs=1035000, position=106570]]
numberOfTracks = 2 numberOfTracks = 2
track 1: track 1:
total output bytes = 89502 total output bytes = 89502

View File

@ -1,14 +1,14 @@
seekMap: seekMap:
isSeekable = true isSeekable = true
duration = 1104000 duration = 1072000
getPosition(0) = [[timeUs=67000, position=5576]] getPosition(0) = [[timeUs=67000, position=5576]]
getPosition(1) = [[timeUs=67000, position=5576]] getPosition(1) = [[timeUs=67000, position=5576]]
getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]] getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]]
getPosition(1104000) = [[timeUs=1035000, position=106570]] getPosition(1072000) = [[timeUs=1035000, position=106570]]
numberOfTracks = 2 numberOfTracks = 2
track 1: track 1:
total output bytes = 29422 total output bytes = 30995
sample count = 20 sample count = 22
format 0: format 0:
id = 1 id = 1
sampleMimeType = video/avc sampleMimeType = video/avc
@ -21,82 +21,90 @@ track 1:
data = length 30, hash F6F3D010 data = length 30, hash F6F3D010
data = length 10, hash 7A0D0F2B data = length 10, hash 7A0D0F2B
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 1: sample 3:
time = 500000 time = 500000
flags = 0 flags = 0
data = length 4852, hash 9DB6979D data = length 4852, hash 9DB6979D
sample 2: sample 4:
time = 467000 time = 467000
flags = 0 flags = 0
data = length 547, hash E31A6979 data = length 547, hash E31A6979
sample 3: sample 5:
time = 434000 time = 434000
flags = 0 flags = 0
data = length 570, hash FEC40D00 data = length 570, hash FEC40D00
sample 4: sample 6:
time = 634000 time = 634000
flags = 0 flags = 0
data = length 5525, hash 7C478F7E data = length 5525, hash 7C478F7E
sample 5: sample 7:
time = 567000 time = 567000
flags = 0 flags = 0
data = length 1082, hash DA07059A data = length 1082, hash DA07059A
sample 6: sample 8:
time = 534000 time = 534000
flags = 0 flags = 0
data = length 807, hash 93478E6B data = length 807, hash 93478E6B
sample 7: sample 9:
time = 600000 time = 600000
flags = 0 flags = 0
data = length 744, hash 9A8E6026 data = length 744, hash 9A8E6026
sample 8: sample 10:
time = 767000 time = 767000
flags = 0 flags = 0
data = length 4732, hash C73B23C0 data = length 4732, hash C73B23C0
sample 9: sample 11:
time = 700000 time = 700000
flags = 0 flags = 0
data = length 1004, hash 8A19A228 data = length 1004, hash 8A19A228
sample 10: sample 12:
time = 667000 time = 667000
flags = 0 flags = 0
data = length 794, hash 8126022C data = length 794, hash 8126022C
sample 11: sample 13:
time = 734000 time = 734000
flags = 0 flags = 0
data = length 645, hash F08300E5 data = length 645, hash F08300E5
sample 12: sample 14:
time = 900000 time = 900000
flags = 0 flags = 0
data = length 2684, hash 727FE378 data = length 2684, hash 727FE378
sample 13: sample 15:
time = 834000 time = 834000
flags = 0 flags = 0
data = length 787, hash 419A7821 data = length 787, hash 419A7821
sample 14: sample 16:
time = 800000 time = 800000
flags = 0 flags = 0
data = length 649, hash 5C159346 data = length 649, hash 5C159346
sample 15: sample 17:
time = 867000 time = 867000
flags = 0 flags = 0
data = length 509, hash F912D655 data = length 509, hash F912D655
sample 16: sample 18:
time = 1034000 time = 1034000
flags = 0 flags = 0
data = length 1226, hash 29815C21 data = length 1226, hash 29815C21
sample 17: sample 19:
time = 967000 time = 967000
flags = 0 flags = 0
data = length 898, hash D997AD0A data = length 898, hash D997AD0A
sample 18: sample 20:
time = 934000 time = 934000
flags = 0 flags = 0
data = length 476, hash A0423645 data = length 476, hash A0423645
sample 19: sample 21:
time = 1000000 time = 1000000
flags = 0 flags = 0
data = length 486, hash DDF32CBB data = length 486, hash DDF32CBB

View File

@ -1,14 +1,14 @@
seekMap: seekMap:
isSeekable = true isSeekable = true
duration = 1104000 duration = 1072000
getPosition(0) = [[timeUs=67000, position=5576]] getPosition(0) = [[timeUs=67000, position=5576]]
getPosition(1) = [[timeUs=67000, position=5576]] getPosition(1) = [[timeUs=67000, position=5576]]
getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]] getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]]
getPosition(1104000) = [[timeUs=1035000, position=106570]] getPosition(1072000) = [[timeUs=1035000, position=106570]]
numberOfTracks = 2 numberOfTracks = 2
track 1: track 1:
total output bytes = 8360 total output bytes = 10158
sample count = 9 sample count = 11
format 0: format 0:
id = 1 id = 1
sampleMimeType = video/avc sampleMimeType = video/avc
@ -21,38 +21,46 @@ track 1:
data = length 30, hash F6F3D010 data = length 30, hash F6F3D010
data = length 10, hash 7A0D0F2B data = length 10, hash 7A0D0F2B
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 1: sample 3:
time = 900000 time = 900000
flags = 0 flags = 0
data = length 2684, hash 727FE378 data = length 2684, hash 727FE378
sample 2: sample 4:
time = 834000 time = 834000
flags = 0 flags = 0
data = length 787, hash 419A7821 data = length 787, hash 419A7821
sample 3: sample 5:
time = 800000 time = 800000
flags = 0 flags = 0
data = length 649, hash 5C159346 data = length 649, hash 5C159346
sample 4: sample 6:
time = 867000 time = 867000
flags = 0 flags = 0
data = length 509, hash F912D655 data = length 509, hash F912D655
sample 5: sample 7:
time = 1034000 time = 1034000
flags = 0 flags = 0
data = length 1226, hash 29815C21 data = length 1226, hash 29815C21
sample 6: sample 8:
time = 967000 time = 967000
flags = 0 flags = 0
data = length 898, hash D997AD0A data = length 898, hash D997AD0A
sample 7: sample 9:
time = 934000 time = 934000
flags = 0 flags = 0
data = length 476, hash A0423645 data = length 476, hash A0423645
sample 8: sample 10:
time = 1000000 time = 1000000
flags = 0 flags = 0
data = length 486, hash DDF32CBB data = length 486, hash DDF32CBB

View File

@ -1,10 +1,10 @@
seekMap: seekMap:
isSeekable = true isSeekable = true
duration = 1104000 duration = 1072000
getPosition(0) = [[timeUs=67000, position=5576]] getPosition(0) = [[timeUs=67000, position=5576]]
getPosition(1) = [[timeUs=67000, position=5576]] getPosition(1) = [[timeUs=67000, position=5576]]
getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]] getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]]
getPosition(1104000) = [[timeUs=1035000, position=106570]] getPosition(1072000) = [[timeUs=1035000, position=106570]]
numberOfTracks = 2 numberOfTracks = 2
track 1: track 1:
total output bytes = 0 total output bytes = 0

View File

@ -1,10 +1,10 @@
seekMap: seekMap:
isSeekable = true isSeekable = true
duration = 1104000 duration = 1072000
getPosition(0) = [[timeUs=67000, position=5576]] getPosition(0) = [[timeUs=67000, position=5576]]
getPosition(1) = [[timeUs=67000, position=5576]] getPosition(1) = [[timeUs=67000, position=5576]]
getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]] getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]]
getPosition(1104000) = [[timeUs=1035000, position=106570]] getPosition(1072000) = [[timeUs=1035000, position=106570]]
numberOfTracks = 2 numberOfTracks = 2
track 1: track 1:
total output bytes = 89502 total output bytes = 89502