diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 531d9edef5..a0d569a5cb 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -20,9 +20,12 @@ for seeking. * Use theme when loading drawables on API 21+ ([#220](https://github.com/androidx/media/issues/220)). +* Extractors: * Throw a ParserException instead of a NullPointerException if the sample table (stbl) is missing a required sample description (stsd) when parsing trak atoms. + * Correctly skip samples when seeking directly to a sync frame in fMP4 + ([#10941](https://github.com/google/ExoPlayer/issues/10941)). * Audio: * Use the compressed audio format bitrate to calculate the min buffer size for `AudioTrack` in direct playbacks (passthrough). diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/mp4/FragmentedMp4Extractor.java b/libraries/extractor/src/main/java/androidx/media3/extractor/mp4/FragmentedMp4Extractor.java index a4f1dfb794..9e3b45da20 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/mp4/FragmentedMp4Extractor.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/mp4/FragmentedMp4Extractor.java @@ -1675,15 +1675,15 @@ public class FragmentedMp4Extractor implements Extractor { } /** - * Advances {@link #firstSampleToOutputIndex} to point to the sync sample before the specified - * seek time in the current fragment. + * Advances {@link #firstSampleToOutputIndex} to point to the sync sample at or before the + * specified seek time in the current fragment. * * @param timeUs The seek time, in microseconds. */ public void seek(long timeUs) { int searchIndex = currentSampleIndex; while (searchIndex < fragment.sampleCount - && fragment.getSamplePresentationTimeUs(searchIndex) < timeUs) { + && fragment.getSamplePresentationTimeUs(searchIndex) <= timeUs) { if (fragment.sampleIsSyncFrameTable[searchIndex]) { firstSampleToOutputIndex = searchIndex; } diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_ac3_fragmented.mp4.1.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_ac3_fragmented.mp4.1.dump index 0f902e441a..4bcb712c34 100644 --- a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_ac3_fragmented.mp4.1.dump +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_ac3_fragmented.mp4.1.dump @@ -7,8 +7,8 @@ seekMap: getPosition(288000) = [[timeUs=0, position=636]] numberOfTracks = 1 track 0: - total output bytes = 10752 - sample count = 7 + total output bytes = 9216 + sample count = 6 format 0: averageBitrate = 384000 peakBitrate = 384000 @@ -18,30 +18,26 @@ track 0: sampleRate = 48000 language = und sample 0: - time = 64000 - flags = 1 - data = length 1536, hash 5D09685 - sample 1: time = 96000 flags = 1 data = length 1536, hash A9A24E44 - sample 2: + sample 1: time = 128000 flags = 1 data = length 1536, hash 6F856273 - sample 3: + sample 2: time = 160000 flags = 1 data = length 1536, hash B1737D3C - sample 4: + sample 3: time = 192000 flags = 1 data = length 1536, hash 98FDEB9D - sample 5: + sample 4: time = 224000 flags = 1 data = length 1536, hash 99B9B943 - sample 6: + sample 5: time = 256000 flags = 1 data = length 1536, hash AAD9FCD2 diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_ac3_fragmented.mp4.2.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_ac3_fragmented.mp4.2.dump index d747be40c5..c03c03e6c0 100644 --- a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_ac3_fragmented.mp4.2.dump +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_ac3_fragmented.mp4.2.dump @@ -7,8 +7,8 @@ seekMap: getPosition(288000) = [[timeUs=0, position=636]] numberOfTracks = 1 track 0: - total output bytes = 6144 - sample count = 4 + total output bytes = 4608 + sample count = 3 format 0: averageBitrate = 384000 peakBitrate = 384000 @@ -18,18 +18,14 @@ track 0: sampleRate = 48000 language = und sample 0: - time = 160000 - flags = 1 - data = length 1536, hash B1737D3C - sample 1: time = 192000 flags = 1 data = length 1536, hash 98FDEB9D - sample 2: + sample 1: time = 224000 flags = 1 data = length 1536, hash 99B9B943 - sample 3: + sample 2: time = 256000 flags = 1 data = length 1536, hash AAD9FCD2 diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_eac3_fragmented.mp4.1.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_eac3_fragmented.mp4.1.dump index 027e7eb633..e33b92c7bc 100644 --- a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_eac3_fragmented.mp4.1.dump +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_eac3_fragmented.mp4.1.dump @@ -7,8 +7,8 @@ seekMap: getPosition(1728000) = [[timeUs=0, position=638]] numberOfTracks = 1 track 0: - total output bytes = 148000 - sample count = 37 + total output bytes = 144000 + sample count = 36 format 0: peakBitrate = 1000000 id = 1 @@ -17,150 +17,146 @@ track 0: sampleRate = 48000 language = und sample 0: - time = 544000 - flags = 1 - data = length 4000, hash 27F20D29 - sample 1: time = 576000 flags = 1 data = length 4000, hash 6F565894 - sample 2: + sample 1: time = 608000 flags = 1 data = length 4000, hash A6F07C4A - sample 3: + sample 2: time = 640000 flags = 1 data = length 4000, hash 3A0CA15C - sample 4: + sample 3: time = 672000 flags = 1 data = length 4000, hash DB365414 - sample 5: + sample 4: time = 704000 flags = 1 data = length 4000, hash 31E08469 - sample 6: + sample 5: time = 736000 flags = 1 data = length 4000, hash 315F5C28 - sample 7: + sample 6: time = 768000 flags = 1 data = length 4000, hash CC65DF80 - sample 8: + sample 7: time = 800000 flags = 1 data = length 4000, hash 503FB64C - sample 9: + sample 8: time = 832000 flags = 1 data = length 4000, hash 817CF735 - sample 10: + sample 9: time = 864000 flags = 1 data = length 4000, hash 37391ADA - sample 11: + sample 10: time = 896000 flags = 1 data = length 4000, hash 37391ADA - sample 12: + sample 11: time = 928000 flags = 1 data = length 4000, hash 64DBF751 - sample 13: + sample 12: time = 960000 flags = 1 data = length 4000, hash 81AE828E - sample 14: + sample 13: time = 992000 flags = 1 data = length 4000, hash 767D6C98 - sample 15: + sample 14: time = 1024000 flags = 1 data = length 4000, hash A5F6D4E - sample 16: + sample 15: time = 1056000 flags = 1 data = length 4000, hash EABC6B0D - sample 17: + sample 16: time = 1088000 flags = 1 data = length 4000, hash F47EF742 - sample 18: + sample 17: time = 1120000 flags = 1 data = length 4000, hash 9B2549DA - sample 19: + sample 18: time = 1152000 flags = 1 data = length 4000, hash A12733C9 - sample 20: + sample 19: time = 1184000 flags = 1 data = length 4000, hash 95F62E99 - sample 21: + sample 20: time = 1216000 flags = 1 data = length 4000, hash A4D858 - sample 22: + sample 21: time = 1248000 flags = 1 data = length 4000, hash A4D858 - sample 23: + sample 22: time = 1280000 flags = 1 data = length 4000, hash 22C1A129 - sample 24: + sample 23: time = 1312000 flags = 1 data = length 4000, hash 2C51E4A1 - sample 25: + sample 24: time = 1344000 flags = 1 data = length 4000, hash 3782E8BB - sample 26: + sample 25: time = 1376000 flags = 1 data = length 4000, hash 2C51E4A1 - sample 27: + sample 26: time = 1408000 flags = 1 data = length 4000, hash BDB3D129 - sample 28: + sample 27: time = 1440000 flags = 1 data = length 4000, hash F642A55 - sample 29: + sample 28: time = 1472000 flags = 1 data = length 4000, hash 32F259F4 - sample 30: + sample 29: time = 1504000 flags = 1 data = length 4000, hash 4C987B7C - sample 31: + sample 30: time = 1536000 flags = 1 data = length 4000, hash 57C98E1C - sample 32: + sample 31: time = 1568000 flags = 1 data = length 4000, hash 4C987B7C - sample 33: + sample 32: time = 1600000 flags = 1 data = length 4000, hash 4C987B7C - sample 34: + sample 33: time = 1632000 flags = 1 data = length 4000, hash 4C987B7C - sample 35: + sample 34: time = 1664000 flags = 1 data = length 4000, hash 4C987B7C - sample 36: + sample 35: time = 1696000 flags = 1 data = length 4000, hash 4C987B7C diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_eac3_fragmented.mp4.2.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_eac3_fragmented.mp4.2.dump index db94e2636e..a079fe334e 100644 --- a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_eac3_fragmented.mp4.2.dump +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_eac3_fragmented.mp4.2.dump @@ -7,8 +7,8 @@ seekMap: getPosition(1728000) = [[timeUs=0, position=638]] numberOfTracks = 1 track 0: - total output bytes = 76000 - sample count = 19 + total output bytes = 72000 + sample count = 18 format 0: peakBitrate = 1000000 id = 1 @@ -17,78 +17,74 @@ track 0: sampleRate = 48000 language = und sample 0: - time = 1120000 - flags = 1 - data = length 4000, hash 9B2549DA - sample 1: time = 1152000 flags = 1 data = length 4000, hash A12733C9 - sample 2: + sample 1: time = 1184000 flags = 1 data = length 4000, hash 95F62E99 - sample 3: + sample 2: time = 1216000 flags = 1 data = length 4000, hash A4D858 - sample 4: + sample 3: time = 1248000 flags = 1 data = length 4000, hash A4D858 - sample 5: + sample 4: time = 1280000 flags = 1 data = length 4000, hash 22C1A129 - sample 6: + sample 5: time = 1312000 flags = 1 data = length 4000, hash 2C51E4A1 - sample 7: + sample 6: time = 1344000 flags = 1 data = length 4000, hash 3782E8BB - sample 8: + sample 7: time = 1376000 flags = 1 data = length 4000, hash 2C51E4A1 - sample 9: + sample 8: time = 1408000 flags = 1 data = length 4000, hash BDB3D129 - sample 10: + sample 9: time = 1440000 flags = 1 data = length 4000, hash F642A55 - sample 11: + sample 10: time = 1472000 flags = 1 data = length 4000, hash 32F259F4 - sample 12: + sample 11: time = 1504000 flags = 1 data = length 4000, hash 4C987B7C - sample 13: + sample 12: time = 1536000 flags = 1 data = length 4000, hash 57C98E1C - sample 14: + sample 13: time = 1568000 flags = 1 data = length 4000, hash 4C987B7C - sample 15: + sample 14: time = 1600000 flags = 1 data = length 4000, hash 4C987B7C - sample 16: + sample 15: time = 1632000 flags = 1 data = length 4000, hash 4C987B7C - sample 17: + sample 16: time = 1664000 flags = 1 data = length 4000, hash 4C987B7C - sample 18: + sample 17: time = 1696000 flags = 1 data = length 4000, hash 4C987B7C