From ec13c4280080d9b57656ead5becc950a768ee8df Mon Sep 17 00:00:00 2001 From: tonihei Date: Mon, 26 Jun 2023 13:26:35 +0000 Subject: [PATCH] Do not trim audio samples by changing their timestamp MP4 edit lists sometimes ask to start playback between two samples. If this happens, we currently change the timestamp of the first sample to zero to trim it (e.g. to display the first frame for a slightly shorter period of time). However, we can't do this to audio samples are they have an inherent duration and trimming them this way is not possible. PiperOrigin-RevId: 543420218 (cherry picked from commit 232246240415443ff8d3a8cd5930273b4085ddaa) --- .../androidx/media3/extractor/mp4/AtomParsers.java | 11 ++++++++++- .../assets/extractordumps/mp4/sample_opus.mp4.0.dump | 2 +- .../mp4/sample_opus.mp4.unknown_length.dump | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/mp4/AtomParsers.java b/libraries/extractor/src/main/java/androidx/media3/extractor/mp4/AtomParsers.java index 0fd3f76203..e97707df5b 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/mp4/AtomParsers.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/mp4/AtomParsers.java @@ -775,7 +775,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; long ptsUs = Util.scaleLargeTimestamp(pts, C.MICROS_PER_SECOND, track.movieTimescale); long timeInSegmentUs = Util.scaleLargeTimestamp( - max(0, timestamps[j] - editMediaTime), C.MICROS_PER_SECOND, track.timescale); + timestamps[j] - editMediaTime, C.MICROS_PER_SECOND, track.timescale); + if (canTrimSamplesWithTimestampChange(track.type)) { + timeInSegmentUs = max(0, timeInSegmentUs); + } editedTimestamps[sampleIndex] = ptsUs + timeInSegmentUs; if (copyMetadata && editedSizes[sampleIndex] > editedMaximumSize) { editedMaximumSize = sizes[j]; @@ -796,6 +799,12 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; editedDurationUs); } + private static boolean canTrimSamplesWithTimestampChange(@C.TrackType int trackType) { + // Audio samples have an inherent duration and we can't trim data by changing the sample + // timestamp alone. + return trackType != C.TRACK_TYPE_AUDIO; + } + @Nullable private static Metadata parseUdtaMeta(ParsableByteArray meta, int limit) { meta.skipBytes(Atom.HEADER_SIZE); diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_opus.mp4.0.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_opus.mp4.0.dump index e78e0264a8..952a09d754 100644 --- a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_opus.mp4.0.dump +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_opus.mp4.0.dump @@ -22,7 +22,7 @@ track 0: data = length 8, hash 72CBCBF5 data = length 8, hash 79C07075 sample 0: - time = 0 + time = -6500 flags = 1 data = length 3, hash 4732 sample 1: diff --git a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_opus.mp4.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_opus.mp4.unknown_length.dump index e78e0264a8..952a09d754 100644 --- a/libraries/test_data/src/test/assets/extractordumps/mp4/sample_opus.mp4.unknown_length.dump +++ b/libraries/test_data/src/test/assets/extractordumps/mp4/sample_opus.mp4.unknown_length.dump @@ -22,7 +22,7 @@ track 0: data = length 8, hash 72CBCBF5 data = length 8, hash 79C07075 sample 0: - time = 0 + time = -6500 flags = 1 data = length 3, hash 4732 sample 1: