Accumulate remainder in buffer duration calculations.

When dropping the remainder, the decoder and encoder timestamps start diverging after a few buffers when no speed changes are supposed to occur. Tracking the remainder keeps them in sync.

PiperOrigin-RevId: 408341074
This commit is contained in:
hschlueter 2021-11-08 15:52:01 +00:00 committed by tonihei
parent ba9ade1c8e
commit 9efa32e49b
2 changed files with 41 additions and 29 deletions

View File

@ -31,7 +31,9 @@ import com.google.android.exoplayer2.audio.AudioProcessor;
import com.google.android.exoplayer2.audio.AudioProcessor.AudioFormat;
import com.google.android.exoplayer2.audio.SonicAudioProcessor;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.common.math.LongMath;
import java.io.IOException;
import java.math.RoundingMode;
import java.nio.ByteBuffer;
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@ -62,6 +64,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
private @MonotonicNonNull AudioFormat encoderInputAudioFormat;
private @MonotonicNonNull MediaCodecAdapterWrapper encoder;
private long nextEncoderInputBufferTimeUs;
private long encoderBufferDurationRemainder;
private ByteBuffer sonicOutputBuffer;
private boolean drainingSonicForSpeedChange;
@ -82,6 +85,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
sonicAudioProcessor = new SonicAudioProcessor();
sonicOutputBuffer = AudioProcessor.EMPTY_BUFFER;
nextEncoderInputBufferTimeUs = 0;
encoderBufferDurationRemainder = 0;
speedProvider = new SegmentSpeedProvider(decoderInputFormat);
currentSpeed = speedProvider.getSpeed(0);
try {
@ -269,7 +273,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
encoderInputBufferData.put(inputBuffer);
encoderInputBuffer.timeUs = nextEncoderInputBufferTimeUs;
nextEncoderInputBufferTimeUs +=
getBufferDurationUs(
getEncoderBufferDurationUs(
/* bytesWritten= */ encoderInputBufferData.position(),
encoderInputAudioFormat.bytesPerFrame,
encoderInputAudioFormat.sampleRate);
@ -366,9 +370,17 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
errorCode);
}
// TODO(internal b/204978301): Ensure encoder and decoder timestamps match when no speed change.
private static long getBufferDurationUs(long bytesWritten, int bytesPerFrame, int sampleRate) {
long framesWritten = bytesWritten / bytesPerFrame;
return framesWritten * C.MICROS_PER_SECOND / sampleRate;
private long getEncoderBufferDurationUs(long bytesWritten, int bytesPerFrame, int sampleRate) {
// The calculation below accounts for remainders and rounding. Without that it corresponds to
// the following:
// bufferDurationUs = numberOfFramesInBuffer * sampleDurationUs
// where numberOfFramesInBuffer = bytesWritten / bytesPerFrame
// and sampleDurationUs = C.MICROS_PER_SECOND / sampleRate
long framesWrittenMicrosPerSecond =
bytesWritten * C.MICROS_PER_SECOND / bytesPerFrame + encoderBufferDurationRemainder;
long bufferDurationUs =
LongMath.divide(framesWrittenMicrosPerSecond, sampleRate, RoundingMode.CEILING);
encoderBufferDurationRemainder = framesWrittenMicrosPerSecond - bufferDurationUs * sampleRate;
return bufferDurationUs;
}
}

View File

@ -135,145 +135,145 @@ sample:
dataHashCode = 1000136444
size = 140
isKeyFrame = true
presentationTimeUs = 416
presentationTimeUs = 417
sample:
trackIndex = 0
dataHashCode = 217961709
size = 172
isKeyFrame = true
presentationTimeUs = 3332
presentationTimeUs = 3334
sample:
trackIndex = 0
dataHashCode = -879376936
size = 176
isKeyFrame = true
presentationTimeUs = 6915
presentationTimeUs = 6917
sample:
trackIndex = 0
dataHashCode = 1259979587
size = 192
isKeyFrame = true
presentationTimeUs = 10581
presentationTimeUs = 10584
sample:
trackIndex = 0
dataHashCode = 907407225
size = 188
isKeyFrame = true
presentationTimeUs = 14581
presentationTimeUs = 14584
sample:
trackIndex = 0
dataHashCode = -904354707
size = 176
isKeyFrame = true
presentationTimeUs = 18497
presentationTimeUs = 18500
sample:
trackIndex = 0
dataHashCode = 1001385853
size = 172
isKeyFrame = true
presentationTimeUs = 22163
presentationTimeUs = 22167
sample:
trackIndex = 0
dataHashCode = 1545716086
size = 196
isKeyFrame = true
presentationTimeUs = 25746
presentationTimeUs = 25750
sample:
trackIndex = 0
dataHashCode = 358710839
size = 180
isKeyFrame = true
presentationTimeUs = 29829
presentationTimeUs = 29834
sample:
trackIndex = 0
dataHashCode = -671124798
size = 140
isKeyFrame = true
presentationTimeUs = 33579
presentationTimeUs = 33584
sample:
trackIndex = 0
dataHashCode = -945404910
size = 120
isKeyFrame = true
presentationTimeUs = 36495
presentationTimeUs = 36500
sample:
trackIndex = 0
dataHashCode = 1881048379
size = 88
isKeyFrame = true
presentationTimeUs = 38995
presentationTimeUs = 39000
sample:
trackIndex = 0
dataHashCode = 1059579897
size = 88
isKeyFrame = true
presentationTimeUs = 40828
presentationTimeUs = 40834
sample:
trackIndex = 0
dataHashCode = 1496098648
size = 84
isKeyFrame = true
presentationTimeUs = 42661
presentationTimeUs = 42667
sample:
trackIndex = 0
dataHashCode = 250093960
size = 751
isKeyFrame = true
presentationTimeUs = 44411
presentationTimeUs = 44417
sample:
trackIndex = 0
dataHashCode = 1895536226
size = 1045
isKeyFrame = true
presentationTimeUs = 59994
presentationTimeUs = 60063
sample:
trackIndex = 0
dataHashCode = 1723596464
size = 947
isKeyFrame = true
presentationTimeUs = 81744
presentationTimeUs = 81834
sample:
trackIndex = 0
dataHashCode = -978803114
size = 946
isKeyFrame = true
presentationTimeUs = 101410
presentationTimeUs = 101563
sample:
trackIndex = 0
dataHashCode = 387377078
size = 946
isKeyFrame = true
presentationTimeUs = 121076
presentationTimeUs = 121271
sample:
trackIndex = 0
dataHashCode = -132658698
size = 901
isKeyFrame = true
presentationTimeUs = 140742
presentationTimeUs = 140980
sample:
trackIndex = 0
dataHashCode = 1495036471
size = 899
isKeyFrame = true
presentationTimeUs = 159492
presentationTimeUs = 159750
sample:
trackIndex = 0
dataHashCode = 304440590
size = 878
isKeyFrame = true
presentationTimeUs = 178158
presentationTimeUs = 178480
sample:
trackIndex = 0
dataHashCode = -1955900344
size = 112
isKeyFrame = true
presentationTimeUs = 196408
presentationTimeUs = 196771
sample:
trackIndex = 0
dataHashCode = 88896626
size = 116
isKeyFrame = true
presentationTimeUs = 198741
presentationTimeUs = 199105
sample:
trackIndex = 1
dataHashCode = 2139021989