Simplify timestamp tracking

An integer multiple/divide can be removed without loss of precision.

PiperOrigin-RevId: 315653905
This commit is contained in:
andrewlewis 2020-06-10 10:13:01 +01:00 committed by Oliver Woodman
parent 0caada8b8c
commit b0457da038

View File

@ -19,7 +19,9 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.audio.MpegAudioUtil; import com.google.android.exoplayer2.audio.MpegAudioUtil;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.Log;
import java.nio.ByteBuffer;
/** /**
* Tracks the number of processed samples to calculate an accurate current timestamp, matching the * Tracks the number of processed samples to calculate an accurate current timestamp, matching the
@ -55,17 +57,15 @@ import com.google.android.exoplayer2.util.Log;
* @return The expected output presentation time, in microseconds. * @return The expected output presentation time, in microseconds.
*/ */
public long updateAndGetPresentationTimeUs(Format format, DecoderInputBuffer buffer) { public long updateAndGetPresentationTimeUs(Format format, DecoderInputBuffer buffer) {
if (seenInvalidMpegAudioHeader || buffer.data == null) { if (seenInvalidMpegAudioHeader) {
return buffer.timeUs; return buffer.timeUs;
} }
// These calculations mirror the timestamp calculations in the Codec2 Mp3 Decoder. ByteBuffer data = Assertions.checkNotNull(buffer.data);
// https://cs.android.com/android/platform/superproject/+/master:frameworks/av/media/codec2/components/mp3/C2SoftMp3Dec.cpp;l=464;drc=ed134640332fea70ca4b05694289d91a5265bb46
long presentationTimeUs = processedSamples * C.MICROS_PER_SECOND / format.sampleRate;
int sampleHeaderData = 0; int sampleHeaderData = 0;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
sampleHeaderData <<= 8; sampleHeaderData <<= 8;
sampleHeaderData |= buffer.data.get(i) & 0xFF; sampleHeaderData |= data.get(i) & 0xFF;
} }
int frameCount = MpegAudioUtil.parseMpegAudioFrameSampleCount(sampleHeaderData); int frameCount = MpegAudioUtil.parseMpegAudioFrameSampleCount(sampleHeaderData);
@ -74,14 +74,20 @@ import com.google.android.exoplayer2.util.Log;
Log.w(TAG, "MPEG audio header is invalid."); Log.w(TAG, "MPEG audio header is invalid.");
return buffer.timeUs; return buffer.timeUs;
} }
long outSize = frameCount * format.channelCount * 2L;
boolean isFirstSample = processedSamples == 0; // These calculations mirror the timestamp calculations in the Codec2 Mp3 Decoder.
long outOffset = 0; // https://cs.android.com/android/platform/superproject/+/master:frameworks/av/media/codec2/components/mp3/C2SoftMp3Dec.cpp;l=464;drc=ed134640332fea70ca4b05694289d91a5265bb46
if (isFirstSample) { if (processedSamples == 0) {
anchorTimestampUs = buffer.timeUs; anchorTimestampUs = buffer.timeUs;
outOffset = DECODER_DELAY_SAMPLES; processedSamples = frameCount - DECODER_DELAY_SAMPLES;
return anchorTimestampUs;
} }
processedSamples += (outSize / (format.channelCount * 2L)) - outOffset; long processedDurationUs = getProcessedDurationUs(format);
return anchorTimestampUs + presentationTimeUs; processedSamples += frameCount;
return anchorTimestampUs + processedDurationUs;
}
private long getProcessedDurationUs(Format format) {
return processedSamples * C.MICROS_PER_SECOND / format.sampleRate;
} }
} }