diff --git a/RELEASENOTES.md b/RELEASENOTES.md index d76ca54b7b3..855b0e94f23 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -12,8 +12,11 @@ checks ([#5568](https://github.com/google/ExoPlayer/issues/5568)). * Decoders: Prefer decoders that advertise format support over ones that do not, even if they are listed lower in the `MediaCodecList`. -* Audio: Fix an issue where not all audio was played out when the configuration - for the underlying track was changing (e.g., at some period transitions). +* Audio: + * Fix an issue where not all audio was played out when the configuration + for the underlying track was changing (e.g., at some period transitions). + * Fix an issue where playback speed was applied inaccurately in playlists + ([#6117](https://github.com/google/ExoPlayer/issues/6117)). * Add a workaround for broken raw audio decoding on Oppo R9 ([#5782](https://github.com/google/ExoPlayer/issues/5782)). * Add VR player demo. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java index f982efa9a7d..e3f753958e7 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java @@ -501,7 +501,7 @@ private void flushAudioProcessors() { } } - private void initialize() throws InitializationException { + private void initialize(long presentationTimeUs) throws InitializationException { // If we're asynchronously releasing a previous audio track then we block until it has been // released. This guarantees that we cannot end up in a state where we have multiple audio // track instances. Without this guarantee it would be possible, in extreme cases, to exhaust @@ -533,11 +533,7 @@ private void initialize() throws InitializationException { } } - playbackParameters = - configuration.canApplyPlaybackParameters - ? audioProcessorChain.applyPlaybackParameters(playbackParameters) - : PlaybackParameters.DEFAULT; - setupAudioProcessors(); + applyPlaybackParameters(playbackParameters, presentationTimeUs); audioTrackPositionTracker.setAudioTrack( audioTrack, @@ -591,15 +587,12 @@ public boolean handleBuffer(ByteBuffer buffer, long presentationTimeUs) configuration = pendingConfiguration; pendingConfiguration = null; } - playbackParameters = - configuration.canApplyPlaybackParameters - ? audioProcessorChain.applyPlaybackParameters(playbackParameters) - : PlaybackParameters.DEFAULT; - setupAudioProcessors(); + // Re-apply playback parameters. + applyPlaybackParameters(playbackParameters, presentationTimeUs); } if (!isInitialized()) { - initialize(); + initialize(presentationTimeUs); if (playing) { play(); } @@ -635,15 +628,7 @@ public boolean handleBuffer(ByteBuffer buffer, long presentationTimeUs) } PlaybackParameters newPlaybackParameters = afterDrainPlaybackParameters; afterDrainPlaybackParameters = null; - newPlaybackParameters = audioProcessorChain.applyPlaybackParameters(newPlaybackParameters); - // Store the position and corresponding media time from which the parameters will apply. - playbackParametersCheckpoints.add( - new PlaybackParametersCheckpoint( - newPlaybackParameters, - Math.max(0, presentationTimeUs), - configuration.framesToDurationUs(getWrittenFrames()))); - // Update the set of active audio processors to take into account the new parameters. - setupAudioProcessors(); + applyPlaybackParameters(newPlaybackParameters, presentationTimeUs); } if (startMediaTimeState == START_NOT_SET) { @@ -857,8 +842,9 @@ public PlaybackParameters setPlaybackParameters(PlaybackParameters playbackParam // parameters apply. afterDrainPlaybackParameters = playbackParameters; } else { - // Update the playback parameters now. - this.playbackParameters = audioProcessorChain.applyPlaybackParameters(playbackParameters); + // Update the playback parameters now. They will be applied to the audio processors during + // initialization. + this.playbackParameters = playbackParameters; } } return this.playbackParameters; @@ -1040,6 +1026,21 @@ public void run() { }.start(); } + private void applyPlaybackParameters( + PlaybackParameters playbackParameters, long presentationTimeUs) { + PlaybackParameters newPlaybackParameters = + configuration.canApplyPlaybackParameters + ? audioProcessorChain.applyPlaybackParameters(playbackParameters) + : PlaybackParameters.DEFAULT; + // Store the position and corresponding media time from which the parameters will apply. + playbackParametersCheckpoints.add( + new PlaybackParametersCheckpoint( + newPlaybackParameters, + /* mediaTimeUs= */ Math.max(0, presentationTimeUs), + /* positionUs= */ configuration.framesToDurationUs(getWrittenFrames()))); + setupAudioProcessors(); + } + private long applySpeedup(long positionUs) { @Nullable PlaybackParametersCheckpoint checkpoint = null; while (!playbackParametersCheckpoints.isEmpty()