Simplify playback parameter state tracking in DefaultAudioSink
This makes it easier to reason about some parts of the code and will eventually allow to easily switch between AudioProcessor- based on AudioSink-based speed adjustment. The current state saves the applicable playback parameters in separate variables depending on which speed adjustment path is used. Moreover, the AudioProcessor-based logic keeps a chain of pending parameter changes and we derive the last applicable one everytime we need the current parameters. After this change, this is simplified by - keeping a common value for playback parameters independent of the actual path we use for adjustment. - keeping the final ("current") parameters directly, instead of deriving it from a chain of yet to be applied parameters. PiperOrigin-RevId: 505097294
This commit is contained in:
parent
5e44af0ad9
commit
3d82846074
@ -495,7 +495,8 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
private AudioAttributes audioAttributes;
|
||||
@Nullable private MediaPositionParameters afterDrainParameters;
|
||||
private MediaPositionParameters mediaPositionParameters;
|
||||
private PlaybackParameters audioTrackPlaybackParameters;
|
||||
private PlaybackParameters playbackParameters;
|
||||
private boolean skipSilenceEnabled;
|
||||
|
||||
@Nullable private ByteBuffer avSyncHeader;
|
||||
private int bytesUntilNextAvSync;
|
||||
@ -552,11 +553,9 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
auxEffectInfo = new AuxEffectInfo(AuxEffectInfo.NO_AUX_EFFECT_ID, 0f);
|
||||
mediaPositionParameters =
|
||||
new MediaPositionParameters(
|
||||
PlaybackParameters.DEFAULT,
|
||||
DEFAULT_SKIP_SILENCE,
|
||||
/* mediaTimeUs= */ 0,
|
||||
/* audioTrackPositionUs= */ 0);
|
||||
audioTrackPlaybackParameters = PlaybackParameters.DEFAULT;
|
||||
PlaybackParameters.DEFAULT, /* mediaTimeUs= */ 0, /* audioTrackPositionUs= */ 0);
|
||||
playbackParameters = PlaybackParameters.DEFAULT;
|
||||
skipSilenceEnabled = DEFAULT_SKIP_SILENCE;
|
||||
mediaPositionParametersCheckpoints = new ArrayDeque<>();
|
||||
initializationExceptionPendingExceptionHolder =
|
||||
new PendingExceptionHolder<>(AUDIO_TRACK_RETRY_DURATION_MS);
|
||||
@ -859,8 +858,8 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
startMediaTimeUsNeedsSync = false;
|
||||
startMediaTimeUsNeedsInit = false;
|
||||
|
||||
if (enableAudioTrackPlaybackParams && Util.SDK_INT >= 23) {
|
||||
setAudioTrackPlaybackParametersV23(audioTrackPlaybackParameters);
|
||||
if (useAudioTrackPlaybackParams()) {
|
||||
setAudioTrackPlaybackParametersV23();
|
||||
}
|
||||
applyAudioProcessorPlaybackParametersAndSkipSilence(presentationTimeUs);
|
||||
|
||||
@ -1213,34 +1212,34 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
|
||||
@Override
|
||||
public void setPlaybackParameters(PlaybackParameters playbackParameters) {
|
||||
playbackParameters =
|
||||
this.playbackParameters =
|
||||
new PlaybackParameters(
|
||||
constrainValue(playbackParameters.speed, MIN_PLAYBACK_SPEED, MAX_PLAYBACK_SPEED),
|
||||
constrainValue(playbackParameters.pitch, MIN_PITCH, MAX_PITCH));
|
||||
if (enableAudioTrackPlaybackParams && Util.SDK_INT >= 23) {
|
||||
setAudioTrackPlaybackParametersV23(playbackParameters);
|
||||
if (useAudioTrackPlaybackParams()) {
|
||||
setAudioTrackPlaybackParametersV23();
|
||||
} else {
|
||||
setAudioProcessorPlaybackParametersAndSkipSilence(
|
||||
playbackParameters, getSkipSilenceEnabled());
|
||||
setAudioProcessorPlaybackParameters(playbackParameters);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlaybackParameters getPlaybackParameters() {
|
||||
return enableAudioTrackPlaybackParams
|
||||
? audioTrackPlaybackParameters
|
||||
: getAudioProcessorPlaybackParameters();
|
||||
return playbackParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkipSilenceEnabled(boolean skipSilenceEnabled) {
|
||||
setAudioProcessorPlaybackParametersAndSkipSilence(
|
||||
getAudioProcessorPlaybackParameters(), skipSilenceEnabled);
|
||||
this.skipSilenceEnabled = skipSilenceEnabled;
|
||||
// Skip silence is applied together with the AudioProcessor playback parameters after draining
|
||||
// the pipeline. Force a drain by re-applying the current playback parameters.
|
||||
setAudioProcessorPlaybackParameters(
|
||||
useAudioTrackPlaybackParams() ? PlaybackParameters.DEFAULT : playbackParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSkipSilenceEnabled() {
|
||||
return getMediaPositionParameters().skipSilence;
|
||||
return skipSilenceEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1433,10 +1432,7 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
framesPerEncodedSample = 0;
|
||||
mediaPositionParameters =
|
||||
new MediaPositionParameters(
|
||||
getAudioProcessorPlaybackParameters(),
|
||||
getSkipSilenceEnabled(),
|
||||
/* mediaTimeUs= */ 0,
|
||||
/* audioTrackPositionUs= */ 0);
|
||||
playbackParameters, /* mediaTimeUs= */ 0, /* audioTrackPositionUs= */ 0);
|
||||
startMediaTimeUs = 0;
|
||||
afterDrainParameters = null;
|
||||
mediaPositionParametersCheckpoints.clear();
|
||||
@ -1452,13 +1448,13 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
}
|
||||
|
||||
@RequiresApi(23)
|
||||
private void setAudioTrackPlaybackParametersV23(PlaybackParameters audioTrackPlaybackParameters) {
|
||||
private void setAudioTrackPlaybackParametersV23() {
|
||||
if (isAudioTrackInitialized()) {
|
||||
PlaybackParams playbackParams =
|
||||
new PlaybackParams()
|
||||
.allowDefaults()
|
||||
.setSpeed(audioTrackPlaybackParameters.speed)
|
||||
.setPitch(audioTrackPlaybackParameters.pitch)
|
||||
.setSpeed(playbackParameters.speed)
|
||||
.setPitch(playbackParameters.pitch)
|
||||
.setAudioFallbackMode(PlaybackParams.AUDIO_FALLBACK_MODE_FAIL);
|
||||
try {
|
||||
audioTrack.setPlaybackParams(playbackParams);
|
||||
@ -1466,63 +1462,48 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
Log.w(TAG, "Failed to set playback params", e);
|
||||
}
|
||||
// Update the speed using the actual effective speed from the audio track.
|
||||
audioTrackPlaybackParameters =
|
||||
playbackParameters =
|
||||
new PlaybackParameters(
|
||||
audioTrack.getPlaybackParams().getSpeed(), audioTrack.getPlaybackParams().getPitch());
|
||||
audioTrackPositionTracker.setAudioTrackPlaybackSpeed(audioTrackPlaybackParameters.speed);
|
||||
}
|
||||
this.audioTrackPlaybackParameters = audioTrackPlaybackParameters;
|
||||
}
|
||||
|
||||
private void setAudioProcessorPlaybackParametersAndSkipSilence(
|
||||
PlaybackParameters playbackParameters, boolean skipSilence) {
|
||||
MediaPositionParameters currentMediaPositionParameters = getMediaPositionParameters();
|
||||
if (!playbackParameters.equals(currentMediaPositionParameters.playbackParameters)
|
||||
|| skipSilence != currentMediaPositionParameters.skipSilence) {
|
||||
MediaPositionParameters mediaPositionParameters =
|
||||
new MediaPositionParameters(
|
||||
playbackParameters,
|
||||
skipSilence,
|
||||
/* mediaTimeUs= */ C.TIME_UNSET,
|
||||
/* audioTrackPositionUs= */ C.TIME_UNSET);
|
||||
if (isAudioTrackInitialized()) {
|
||||
// Drain the audio processors so we can determine the frame position at which the new
|
||||
// parameters apply.
|
||||
this.afterDrainParameters = mediaPositionParameters;
|
||||
} else {
|
||||
// Update the audio processor chain parameters now. They will be applied to the audio
|
||||
// processors during initialization.
|
||||
this.mediaPositionParameters = mediaPositionParameters;
|
||||
}
|
||||
audioTrackPositionTracker.setAudioTrackPlaybackSpeed(playbackParameters.speed);
|
||||
}
|
||||
}
|
||||
|
||||
private PlaybackParameters getAudioProcessorPlaybackParameters() {
|
||||
return getMediaPositionParameters().playbackParameters;
|
||||
}
|
||||
|
||||
private MediaPositionParameters getMediaPositionParameters() {
|
||||
// Mask the already set parameters.
|
||||
return afterDrainParameters != null
|
||||
? afterDrainParameters
|
||||
: !mediaPositionParametersCheckpoints.isEmpty()
|
||||
? mediaPositionParametersCheckpoints.getLast()
|
||||
: mediaPositionParameters;
|
||||
private void setAudioProcessorPlaybackParameters(PlaybackParameters playbackParameters) {
|
||||
MediaPositionParameters mediaPositionParameters =
|
||||
new MediaPositionParameters(
|
||||
playbackParameters,
|
||||
/* mediaTimeUs= */ C.TIME_UNSET,
|
||||
/* audioTrackPositionUs= */ C.TIME_UNSET);
|
||||
if (isAudioTrackInitialized()) {
|
||||
// Drain the audio processors so we can determine the frame position at which the new
|
||||
// parameters apply.
|
||||
this.afterDrainParameters = mediaPositionParameters;
|
||||
} else {
|
||||
// Update the audio processor chain parameters now. They will be applied to the audio
|
||||
// processors during initialization.
|
||||
this.mediaPositionParameters = mediaPositionParameters;
|
||||
}
|
||||
}
|
||||
|
||||
private void applyAudioProcessorPlaybackParametersAndSkipSilence(long presentationTimeUs) {
|
||||
PlaybackParameters playbackParameters =
|
||||
PlaybackParameters audioProcessorPlaybackParameters;
|
||||
if (!useAudioTrackPlaybackParams()) {
|
||||
playbackParameters =
|
||||
shouldApplyAudioProcessorPlaybackParameters()
|
||||
? audioProcessorChain.applyPlaybackParameters(playbackParameters)
|
||||
: PlaybackParameters.DEFAULT;
|
||||
audioProcessorPlaybackParameters = playbackParameters;
|
||||
} else {
|
||||
audioProcessorPlaybackParameters = PlaybackParameters.DEFAULT;
|
||||
}
|
||||
skipSilenceEnabled =
|
||||
shouldApplyAudioProcessorPlaybackParameters()
|
||||
? audioProcessorChain.applyPlaybackParameters(getAudioProcessorPlaybackParameters())
|
||||
: PlaybackParameters.DEFAULT;
|
||||
boolean skipSilenceEnabled =
|
||||
shouldApplyAudioProcessorPlaybackParameters()
|
||||
? audioProcessorChain.applySkipSilenceEnabled(getSkipSilenceEnabled())
|
||||
? audioProcessorChain.applySkipSilenceEnabled(skipSilenceEnabled)
|
||||
: DEFAULT_SKIP_SILENCE;
|
||||
mediaPositionParametersCheckpoints.add(
|
||||
new MediaPositionParameters(
|
||||
playbackParameters,
|
||||
skipSilenceEnabled,
|
||||
audioProcessorPlaybackParameters,
|
||||
/* mediaTimeUs= */ max(0, presentationTimeUs),
|
||||
/* audioTrackPositionUs= */ configuration.framesToDurationUs(getWrittenFrames())));
|
||||
setupAudioProcessors();
|
||||
@ -1548,6 +1529,10 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
&& !shouldUseFloatOutput(configuration.inputFormat.pcmEncoding);
|
||||
}
|
||||
|
||||
private boolean useAudioTrackPlaybackParams() {
|
||||
return configuration != null && enableAudioTrackPlaybackParams && Util.SDK_INT >= 23;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether audio in the specified PCM encoding should be written to the audio track as
|
||||
* float PCM.
|
||||
@ -1869,20 +1854,14 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
|
||||
/** The playback parameters. */
|
||||
public final PlaybackParameters playbackParameters;
|
||||
/** Whether to skip silences. */
|
||||
public final boolean skipSilence;
|
||||
/** The media time from which the playback parameters apply, in microseconds. */
|
||||
public final long mediaTimeUs;
|
||||
/** The audio track position from which the playback parameters apply, in microseconds. */
|
||||
public final long audioTrackPositionUs;
|
||||
|
||||
private MediaPositionParameters(
|
||||
PlaybackParameters playbackParameters,
|
||||
boolean skipSilence,
|
||||
long mediaTimeUs,
|
||||
long audioTrackPositionUs) {
|
||||
PlaybackParameters playbackParameters, long mediaTimeUs, long audioTrackPositionUs) {
|
||||
this.playbackParameters = playbackParameters;
|
||||
this.skipSilence = skipSilence;
|
||||
this.mediaTimeUs = mediaTimeUs;
|
||||
this.audioTrackPositionUs = audioTrackPositionUs;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user