diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/mkv/MatroskaExtractor.java b/libraries/extractor/src/main/java/androidx/media3/extractor/mkv/MatroskaExtractor.java index 6519eb1891..9e500dfc88 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/mkv/MatroskaExtractor.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/mkv/MatroskaExtractor.java @@ -1898,17 +1898,25 @@ public class MatroskaExtractor implements Extractor { sizes[i] = (int) (offsets[i + 1] - offsets[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]; - 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); + // Start from the last cue point and move backward until a valid duration is found. + int lastValidIndex = cuePointsSize - 1; + while (lastValidIndex > 0 && timesUs[lastValidIndex] > durationUs) { + lastValidIndex--; + } + + // 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); diff --git a/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.0.dump b/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.0.dump index d31f181dd0..0f80782c2a 100644 --- a/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.0.dump @@ -1,10 +1,10 @@ seekMap: isSeekable = true - duration = 1104000 + duration = 1072000 getPosition(0) = [[timeUs=67000, position=5576]] getPosition(1) = [[timeUs=67000, position=5576]] - getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]] - getPosition(1104000) = [[timeUs=1035000, position=106570]] + getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]] + getPosition(1072000) = [[timeUs=1035000, position=106570]] numberOfTracks = 2 track 1: total output bytes = 89502 diff --git a/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.1.dump b/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.1.dump index 749aee4faa..c8a800aee8 100644 --- a/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.1.dump +++ b/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.1.dump @@ -1,14 +1,14 @@ seekMap: isSeekable = true - duration = 1104000 + duration = 1072000 getPosition(0) = [[timeUs=67000, position=5576]] getPosition(1) = [[timeUs=67000, position=5576]] - getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]] - getPosition(1104000) = [[timeUs=1035000, position=106570]] + getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]] + getPosition(1072000) = [[timeUs=1035000, position=106570]] numberOfTracks = 2 track 1: - total output bytes = 29422 - sample count = 20 + total output bytes = 30995 + sample count = 22 format 0: id = 1 sampleMimeType = video/avc @@ -21,82 +21,90 @@ track 1: data = length 30, hash F6F3D010 data = length 10, hash 7A0D0F2B 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 flags = 0 data = length 405, hash 5CC7F4E7 - sample 1: + sample 3: time = 500000 flags = 0 data = length 4852, hash 9DB6979D - sample 2: + sample 4: time = 467000 flags = 0 data = length 547, hash E31A6979 - sample 3: + sample 5: time = 434000 flags = 0 data = length 570, hash FEC40D00 - sample 4: + sample 6: time = 634000 flags = 0 data = length 5525, hash 7C478F7E - sample 5: + sample 7: time = 567000 flags = 0 data = length 1082, hash DA07059A - sample 6: + sample 8: time = 534000 flags = 0 data = length 807, hash 93478E6B - sample 7: + sample 9: time = 600000 flags = 0 data = length 744, hash 9A8E6026 - sample 8: + sample 10: time = 767000 flags = 0 data = length 4732, hash C73B23C0 - sample 9: + sample 11: time = 700000 flags = 0 data = length 1004, hash 8A19A228 - sample 10: + sample 12: time = 667000 flags = 0 data = length 794, hash 8126022C - sample 11: + sample 13: time = 734000 flags = 0 data = length 645, hash F08300E5 - sample 12: + sample 14: time = 900000 flags = 0 data = length 2684, hash 727FE378 - sample 13: + sample 15: time = 834000 flags = 0 data = length 787, hash 419A7821 - sample 14: + sample 16: time = 800000 flags = 0 data = length 649, hash 5C159346 - sample 15: + sample 17: time = 867000 flags = 0 data = length 509, hash F912D655 - sample 16: + sample 18: time = 1034000 flags = 0 data = length 1226, hash 29815C21 - sample 17: + sample 19: time = 967000 flags = 0 data = length 898, hash D997AD0A - sample 18: + sample 20: time = 934000 flags = 0 data = length 476, hash A0423645 - sample 19: + sample 21: time = 1000000 flags = 0 data = length 486, hash DDF32CBB diff --git a/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.2.dump b/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.2.dump index d7bbab9459..c6769bb5ca 100644 --- a/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.2.dump +++ b/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.2.dump @@ -1,14 +1,14 @@ seekMap: isSeekable = true - duration = 1104000 + duration = 1072000 getPosition(0) = [[timeUs=67000, position=5576]] getPosition(1) = [[timeUs=67000, position=5576]] - getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]] - getPosition(1104000) = [[timeUs=1035000, position=106570]] + getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]] + getPosition(1072000) = [[timeUs=1035000, position=106570]] numberOfTracks = 2 track 1: - total output bytes = 8360 - sample count = 9 + total output bytes = 10158 + sample count = 11 format 0: id = 1 sampleMimeType = video/avc @@ -21,38 +21,46 @@ track 1: data = length 30, hash F6F3D010 data = length 10, hash 7A0D0F2B 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 flags = 0 data = length 645, hash F08300E5 - sample 1: + sample 3: time = 900000 flags = 0 data = length 2684, hash 727FE378 - sample 2: + sample 4: time = 834000 flags = 0 data = length 787, hash 419A7821 - sample 3: + sample 5: time = 800000 flags = 0 data = length 649, hash 5C159346 - sample 4: + sample 6: time = 867000 flags = 0 data = length 509, hash F912D655 - sample 5: + sample 7: time = 1034000 flags = 0 data = length 1226, hash 29815C21 - sample 6: + sample 8: time = 967000 flags = 0 data = length 898, hash D997AD0A - sample 7: + sample 9: time = 934000 flags = 0 data = length 476, hash A0423645 - sample 8: + sample 10: time = 1000000 flags = 0 data = length 486, hash DDF32CBB diff --git a/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.3.dump b/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.3.dump index f99f632e2f..32dfc5b576 100644 --- a/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.3.dump +++ b/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.3.dump @@ -1,10 +1,10 @@ seekMap: isSeekable = true - duration = 1104000 + duration = 1072000 getPosition(0) = [[timeUs=67000, position=5576]] getPosition(1) = [[timeUs=67000, position=5576]] - getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]] - getPosition(1104000) = [[timeUs=1035000, position=106570]] + getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]] + getPosition(1072000) = [[timeUs=1035000, position=106570]] numberOfTracks = 2 track 1: total output bytes = 0 diff --git a/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.unknown_length.dump index d31f181dd0..0f80782c2a 100644 --- a/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.unknown_length.dump @@ -1,10 +1,10 @@ seekMap: isSeekable = true - duration = 1104000 + duration = 1072000 getPosition(0) = [[timeUs=67000, position=5576]] getPosition(1) = [[timeUs=67000, position=5576]] - getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]] - getPosition(1104000) = [[timeUs=1035000, position=106570]] + getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]] + getPosition(1072000) = [[timeUs=1035000, position=106570]] numberOfTracks = 2 track 1: total output bytes = 89502