Refactor buffer duration calculation for clarity.

Follow-up to address comments from 9efa32e49b.

PiperOrigin-RevId: 408600470
This commit is contained in:
hschlueter 2021-11-09 15:04:39 +00:00 committed by tonihei
parent 4082d8a63d
commit 30c77e8e1c

View File

@ -31,9 +31,7 @@ import com.google.android.exoplayer2.audio.AudioProcessor;
import com.google.android.exoplayer2.audio.AudioProcessor.AudioFormat; import com.google.android.exoplayer2.audio.AudioProcessor.AudioFormat;
import com.google.android.exoplayer2.audio.SonicAudioProcessor; import com.google.android.exoplayer2.audio.SonicAudioProcessor;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.common.math.LongMath;
import java.io.IOException; import java.io.IOException;
import java.math.RoundingMode;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@ -84,8 +82,6 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED); new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED);
sonicAudioProcessor = new SonicAudioProcessor(); sonicAudioProcessor = new SonicAudioProcessor();
sonicOutputBuffer = AudioProcessor.EMPTY_BUFFER; sonicOutputBuffer = AudioProcessor.EMPTY_BUFFER;
nextEncoderInputBufferTimeUs = 0;
encoderBufferDurationRemainder = 0;
speedProvider = new SegmentSpeedProvider(decoderInputFormat); speedProvider = new SegmentSpeedProvider(decoderInputFormat);
currentSpeed = speedProvider.getSpeed(0); currentSpeed = speedProvider.getSpeed(0);
try { try {
@ -272,11 +268,10 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
inputBuffer.limit(min(bufferLimit, inputBuffer.position() + encoderInputBufferData.capacity())); inputBuffer.limit(min(bufferLimit, inputBuffer.position() + encoderInputBufferData.capacity()));
encoderInputBufferData.put(inputBuffer); encoderInputBufferData.put(inputBuffer);
encoderInputBuffer.timeUs = nextEncoderInputBufferTimeUs; encoderInputBuffer.timeUs = nextEncoderInputBufferTimeUs;
nextEncoderInputBufferTimeUs += computeNextEncoderInputBufferTimeUs(
getEncoderBufferDurationUs( /* bytesWritten= */ encoderInputBufferData.position(),
/* bytesWritten= */ encoderInputBufferData.position(), encoderInputAudioFormat.bytesPerFrame,
encoderInputAudioFormat.bytesPerFrame, encoderInputAudioFormat.sampleRate);
encoderInputAudioFormat.sampleRate);
encoderInputBuffer.setFlags(0); encoderInputBuffer.setFlags(0);
encoderInputBuffer.flip(); encoderInputBuffer.flip();
inputBuffer.limit(bufferLimit); inputBuffer.limit(bufferLimit);
@ -370,17 +365,21 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
errorCode); errorCode);
} }
private long getEncoderBufferDurationUs(long bytesWritten, int bytesPerFrame, int sampleRate) { private void computeNextEncoderInputBufferTimeUs(
long bytesWritten, int bytesPerFrame, int sampleRate) {
// The calculation below accounts for remainders and rounding. Without that it corresponds to // The calculation below accounts for remainders and rounding. Without that it corresponds to
// the following: // the following:
// bufferDurationUs = numberOfFramesInBuffer * sampleDurationUs // bufferDurationUs = numberOfFramesInBuffer * sampleDurationUs
// where numberOfFramesInBuffer = bytesWritten / bytesPerFrame // where numberOfFramesInBuffer = bytesWritten / bytesPerFrame
// and sampleDurationUs = C.MICROS_PER_SECOND / sampleRate // and sampleDurationUs = C.MICROS_PER_SECOND / sampleRate
long framesWrittenMicrosPerSecond = long numerator = bytesWritten * C.MICROS_PER_SECOND + encoderBufferDurationRemainder;
bytesWritten * C.MICROS_PER_SECOND / bytesPerFrame + encoderBufferDurationRemainder; long denominator = (long) bytesPerFrame * sampleRate;
long bufferDurationUs = long bufferDurationUs = numerator / denominator;
LongMath.divide(framesWrittenMicrosPerSecond, sampleRate, RoundingMode.CEILING); encoderBufferDurationRemainder = numerator - bufferDurationUs * denominator;
encoderBufferDurationRemainder = framesWrittenMicrosPerSecond - bufferDurationUs * sampleRate; if (encoderBufferDurationRemainder > 0) { // Ceil division result.
return bufferDurationUs; bufferDurationUs += 1;
encoderBufferDurationRemainder -= denominator;
}
nextEncoderInputBufferTimeUs += bufferDurationUs;
} }
} }