Skip to content

Commit 7ec61f1

Browse files
rohitjoinsivanbuper
authored andcommitted
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 (cherry picked from commit b1f2efd)
1 parent c44d509 commit 7ec61f1

File tree

6 files changed

+81
-57
lines changed

6 files changed

+81
-57
lines changed

libraries/extractor/src/main/java/androidx/media3/extractor/mkv/MatroskaExtractor.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,17 +1898,25 @@ private SeekMap buildSeekMap(
18981898
sizes[i] = (int) (offsets[i + 1] - offsets[i]);
18991899
durationsUs[i] = timesUs[i + 1] - timesUs[i];
19001900
}
1901-
sizes[cuePointsSize - 1] =
1902-
(int) (segmentContentPosition + segmentContentSize - offsets[cuePointsSize - 1]);
1903-
durationsUs[cuePointsSize - 1] = durationUs - timesUs[cuePointsSize - 1];
1904-
1905-
long lastDurationUs = durationsUs[cuePointsSize - 1];
1906-
if (lastDurationUs <= 0) {
1907-
Log.w(TAG, "Discarding last cue point with unexpected duration: " + lastDurationUs);
1908-
sizes = Arrays.copyOf(sizes, sizes.length - 1);
1909-
offsets = Arrays.copyOf(offsets, offsets.length - 1);
1910-
durationsUs = Arrays.copyOf(durationsUs, durationsUs.length - 1);
1911-
timesUs = Arrays.copyOf(timesUs, timesUs.length - 1);
1901+
1902+
// Start from the last cue point and move backward until a valid duration is found.
1903+
int lastValidIndex = cuePointsSize - 1;
1904+
while (lastValidIndex > 0 && timesUs[lastValidIndex] > durationUs) {
1905+
lastValidIndex--;
1906+
}
1907+
1908+
// Calculate sizes and durations for the last valid index
1909+
sizes[lastValidIndex] =
1910+
(int) (segmentContentPosition + segmentContentSize - offsets[lastValidIndex]);
1911+
durationsUs[lastValidIndex] = durationUs - timesUs[lastValidIndex];
1912+
1913+
// If the last valid index is not the last cue point, truncate the arrays
1914+
if (lastValidIndex < cuePointsSize - 1) {
1915+
Log.w(TAG, "Discarding trailing cue points with timestamps greater than total duration");
1916+
sizes = Arrays.copyOf(sizes, lastValidIndex + 1);
1917+
offsets = Arrays.copyOf(offsets, lastValidIndex + 1);
1918+
durationsUs = Arrays.copyOf(durationsUs, lastValidIndex + 1);
1919+
timesUs = Arrays.copyOf(timesUs, lastValidIndex + 1);
19121920
}
19131921

19141922
return new ChunkIndex(sizes, offsets, durationsUs, timesUs);

libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.0.dump

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
seekMap:
22
isSeekable = true
3-
duration = 1104000
3+
duration = 1072000
44
getPosition(0) = [[timeUs=67000, position=5576]]
55
getPosition(1) = [[timeUs=67000, position=5576]]
6-
getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]]
7-
getPosition(1104000) = [[timeUs=1035000, position=106570]]
6+
getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]]
7+
getPosition(1072000) = [[timeUs=1035000, position=106570]]
88
numberOfTracks = 2
99
track 1:
1010
total output bytes = 89502

libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.1.dump

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
seekMap:
22
isSeekable = true
3-
duration = 1104000
3+
duration = 1072000
44
getPosition(0) = [[timeUs=67000, position=5576]]
55
getPosition(1) = [[timeUs=67000, position=5576]]
6-
getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]]
7-
getPosition(1104000) = [[timeUs=1035000, position=106570]]
6+
getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]]
7+
getPosition(1072000) = [[timeUs=1035000, position=106570]]
88
numberOfTracks = 2
99
track 1:
10-
total output bytes = 29422
11-
sample count = 20
10+
total output bytes = 30995
11+
sample count = 22
1212
format 0:
1313
id = 1
1414
sampleMimeType = video/avc
@@ -21,82 +21,90 @@ track 1:
2121
data = length 30, hash F6F3D010
2222
data = length 10, hash 7A0D0F2B
2323
sample 0:
24+
time = 334000
25+
flags = 0
26+
data = length 953, hash 7160C661
27+
sample 1:
28+
time = 300000
29+
flags = 0
30+
data = length 620, hash 7A7AE07C
31+
sample 2:
2432
time = 367000
2533
flags = 0
2634
data = length 405, hash 5CC7F4E7
27-
sample 1:
35+
sample 3:
2836
time = 500000
2937
flags = 0
3038
data = length 4852, hash 9DB6979D
31-
sample 2:
39+
sample 4:
3240
time = 467000
3341
flags = 0
3442
data = length 547, hash E31A6979
35-
sample 3:
43+
sample 5:
3644
time = 434000
3745
flags = 0
3846
data = length 570, hash FEC40D00
39-
sample 4:
47+
sample 6:
4048
time = 634000
4149
flags = 0
4250
data = length 5525, hash 7C478F7E
43-
sample 5:
51+
sample 7:
4452
time = 567000
4553
flags = 0
4654
data = length 1082, hash DA07059A
47-
sample 6:
55+
sample 8:
4856
time = 534000
4957
flags = 0
5058
data = length 807, hash 93478E6B
51-
sample 7:
59+
sample 9:
5260
time = 600000
5361
flags = 0
5462
data = length 744, hash 9A8E6026
55-
sample 8:
63+
sample 10:
5664
time = 767000
5765
flags = 0
5866
data = length 4732, hash C73B23C0
59-
sample 9:
67+
sample 11:
6068
time = 700000
6169
flags = 0
6270
data = length 1004, hash 8A19A228
63-
sample 10:
71+
sample 12:
6472
time = 667000
6573
flags = 0
6674
data = length 794, hash 8126022C
67-
sample 11:
75+
sample 13:
6876
time = 734000
6977
flags = 0
7078
data = length 645, hash F08300E5
71-
sample 12:
79+
sample 14:
7280
time = 900000
7381
flags = 0
7482
data = length 2684, hash 727FE378
75-
sample 13:
83+
sample 15:
7684
time = 834000
7785
flags = 0
7886
data = length 787, hash 419A7821
79-
sample 14:
87+
sample 16:
8088
time = 800000
8189
flags = 0
8290
data = length 649, hash 5C159346
83-
sample 15:
91+
sample 17:
8492
time = 867000
8593
flags = 0
8694
data = length 509, hash F912D655
87-
sample 16:
95+
sample 18:
8896
time = 1034000
8997
flags = 0
9098
data = length 1226, hash 29815C21
91-
sample 17:
99+
sample 19:
92100
time = 967000
93101
flags = 0
94102
data = length 898, hash D997AD0A
95-
sample 18:
103+
sample 20:
96104
time = 934000
97105
flags = 0
98106
data = length 476, hash A0423645
99-
sample 19:
107+
sample 21:
100108
time = 1000000
101109
flags = 0
102110
data = length 486, hash DDF32CBB

libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.2.dump

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
seekMap:
22
isSeekable = true
3-
duration = 1104000
3+
duration = 1072000
44
getPosition(0) = [[timeUs=67000, position=5576]]
55
getPosition(1) = [[timeUs=67000, position=5576]]
6-
getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]]
7-
getPosition(1104000) = [[timeUs=1035000, position=106570]]
6+
getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]]
7+
getPosition(1072000) = [[timeUs=1035000, position=106570]]
88
numberOfTracks = 2
99
track 1:
10-
total output bytes = 8360
11-
sample count = 9
10+
total output bytes = 10158
11+
sample count = 11
1212
format 0:
1313
id = 1
1414
sampleMimeType = video/avc
@@ -21,38 +21,46 @@ track 1:
2121
data = length 30, hash F6F3D010
2222
data = length 10, hash 7A0D0F2B
2323
sample 0:
24+
time = 700000
25+
flags = 0
26+
data = length 1004, hash 8A19A228
27+
sample 1:
28+
time = 667000
29+
flags = 0
30+
data = length 794, hash 8126022C
31+
sample 2:
2432
time = 734000
2533
flags = 0
2634
data = length 645, hash F08300E5
27-
sample 1:
35+
sample 3:
2836
time = 900000
2937
flags = 0
3038
data = length 2684, hash 727FE378
31-
sample 2:
39+
sample 4:
3240
time = 834000
3341
flags = 0
3442
data = length 787, hash 419A7821
35-
sample 3:
43+
sample 5:
3644
time = 800000
3745
flags = 0
3846
data = length 649, hash 5C159346
39-
sample 4:
47+
sample 6:
4048
time = 867000
4149
flags = 0
4250
data = length 509, hash F912D655
43-
sample 5:
51+
sample 7:
4452
time = 1034000
4553
flags = 0
4654
data = length 1226, hash 29815C21
47-
sample 6:
55+
sample 8:
4856
time = 967000
4957
flags = 0
5058
data = length 898, hash D997AD0A
51-
sample 7:
59+
sample 9:
5260
time = 934000
5361
flags = 0
5462
data = length 476, hash A0423645
55-
sample 8:
63+
sample 10:
5664
time = 1000000
5765
flags = 0
5866
data = length 486, hash DDF32CBB

libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.3.dump

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
seekMap:
22
isSeekable = true
3-
duration = 1104000
3+
duration = 1072000
44
getPosition(0) = [[timeUs=67000, position=5576]]
55
getPosition(1) = [[timeUs=67000, position=5576]]
6-
getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]]
7-
getPosition(1104000) = [[timeUs=1035000, position=106570]]
6+
getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]]
7+
getPosition(1072000) = [[timeUs=1035000, position=106570]]
88
numberOfTracks = 2
99
track 1:
1010
total output bytes = 0

libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.unknown_length.dump

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
seekMap:
22
isSeekable = true
3-
duration = 1104000
3+
duration = 1072000
44
getPosition(0) = [[timeUs=67000, position=5576]]
55
getPosition(1) = [[timeUs=67000, position=5576]]
6-
getPosition(552000) = [[timeUs=547000, position=77334], [timeUs=567000, position=84155]]
7-
getPosition(1104000) = [[timeUs=1035000, position=106570]]
6+
getPosition(536000) = [[timeUs=534000, position=84155], [timeUs=547000, position=77334]]
7+
getPosition(1072000) = [[timeUs=1035000, position=106570]]
88
numberOfTracks = 2
99
track 1:
1010
total output bytes = 89502

0 commit comments

Comments
 (0)