Skip to content

Commit

Permalink
Factor out RTP timestamp to sample time method
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 465337074
  • Loading branch information
claincly authored and marcbaechinger committed Oct 19, 2022
1 parent fe2b846 commit a1be6d6
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.rtsp.reader;

import static com.google.android.exoplayer2.source.rtsp.reader.RtpReaderUtils.toSampleTimeUs;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;

import com.google.android.exoplayer2.C;
Expand Down Expand Up @@ -153,14 +154,4 @@ private static void outputSampleMetadata(TrackOutput trackOutput, long sampleTim
trackOutput.sampleMetadata(
sampleTimeUs, C.BUFFER_FLAG_KEY_FRAME, size, /* offset= */ 0, /* cryptoData= */ null);
}

/** Returns the correct sample time from RTP timestamp, accounting for the AAC sampling rate. */
private static long toSampleTimeUs(
long startTimeOffsetUs, long rtpTimestamp, long firstReceivedRtpTimestamp, int sampleRate) {
return startTimeOffsetUs
+ Util.scaleLargeTimestamp(
rtpTimestamp - firstReceivedRtpTimestamp,
/* multiplier= */ C.MICROS_PER_SECOND,
/* divisor= */ sampleRate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.rtsp.reader;

import static com.google.android.exoplayer2.source.rtsp.reader.RtpReaderUtils.toSampleTimeUs;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Util.castNonNull;
Expand All @@ -26,7 +27,6 @@
import com.google.android.exoplayer2.source.rtsp.RtpPayloadFormat;
import com.google.android.exoplayer2.util.ParsableBitArray;
import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;

/** Parses an AC3 byte stream carried on RTP packets, and extracts AC3 frames. */
Expand Down Expand Up @@ -206,14 +206,4 @@ private void outputSampleMetadataForFragmentedPackets() {
/* cryptoData= */ null);
numBytesPendingMetadataOutput = 0;
}

/** Returns the correct sample time from RTP timestamp, accounting for the AC3 sampling rate. */
private static long toSampleTimeUs(
long startTimeOffsetUs, long rtpTimestamp, long firstReceivedRtpTimestamp, int sampleRate) {
return startTimeOffsetUs
+ Util.scaleLargeTimestamp(
rtpTimestamp - firstReceivedRtpTimestamp,
/* multiplier= */ C.MICROS_PER_SECOND,
/* divisor= */ sampleRate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.rtsp.reader;

import static com.google.android.exoplayer2.source.rtsp.reader.RtpReaderUtils.toSampleTimeUs;
import static com.google.android.exoplayer2.util.Assertions.checkArgument;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
Expand Down Expand Up @@ -183,14 +184,4 @@ public static int getFrameSize(int frameType, boolean isWideBand) {
? AMR_WB_FRAME_TYPE_INDEX_TO_FRAME_SIZE[frameType]
: AMR_NB_FRAME_TYPE_INDEX_TO_FRAME_SIZE[frameType];
}

/** Returns the correct sample time from RTP timestamp, accounting for the AMR sampling rate. */
private static long toSampleTimeUs(
long startTimeOffsetUs, long rtpTimestamp, long firstReceivedRtpTimestamp, int sampleRate) {
return startTimeOffsetUs
+ Util.scaleLargeTimestamp(
rtpTimestamp - firstReceivedRtpTimestamp,
/* multiplier= */ C.MICROS_PER_SECOND,
/* divisor= */ sampleRate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.rtsp.reader;

import static com.google.android.exoplayer2.source.rtsp.reader.RtpReaderUtils.toSampleTimeUs;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
Expand All @@ -35,7 +36,7 @@
/* package */ final class RtpH263Reader implements RtpPayloadReader {
private static final String TAG = "RtpH263Reader";

private static final long MEDIA_CLOCK_FREQUENCY = 90_000;
private static final int MEDIA_CLOCK_FREQUENCY = 90_000;

/** I-frame VOP unit type. */
private static final int I_VOP = 0;
Expand Down Expand Up @@ -164,7 +165,8 @@ public void consume(
// Write the video sample.
trackOutput.sampleData(data, fragmentSize);
fragmentedSampleSizeBytes += fragmentSize;
fragmentedSampleTimeUs = toSampleUs(startTimeOffsetUs, timestamp, firstReceivedTimestamp);
fragmentedSampleTimeUs =
toSampleTimeUs(startTimeOffsetUs, timestamp, firstReceivedTimestamp, MEDIA_CLOCK_FREQUENCY);

if (rtpMarker) {
outputSampleMetadataForFragmentedPackets();
Expand Down Expand Up @@ -242,13 +244,4 @@ private void outputSampleMetadataForFragmentedPackets() {
isKeyFrame = false;
gotFirstPacketOfH263Frame = false;
}

private static long toSampleUs(
long startTimeOffsetUs, long rtpTimestamp, long firstReceivedRtpTimestamp) {
return startTimeOffsetUs
+ Util.scaleLargeTimestamp(
(rtpTimestamp - firstReceivedRtpTimestamp),
/* multiplier= */ C.MICROS_PER_SECOND,
/* divisor= */ MEDIA_CLOCK_FREQUENCY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.rtsp.reader;

import static com.google.android.exoplayer2.source.rtsp.reader.RtpReaderUtils.toSampleTimeUs;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
import static com.google.android.exoplayer2.util.Util.castNonNull;
Expand All @@ -36,7 +37,7 @@
/* package */ final class RtpH264Reader implements RtpPayloadReader {
private static final String TAG = "RtpH264Reader";

private static final long MEDIA_CLOCK_FREQUENCY = 90_000;
private static final int MEDIA_CLOCK_FREQUENCY = 90_000;

/** Offset of payload data within a FU type A payload. */
private static final int FU_PAYLOAD_OFFSET = 2;
Expand Down Expand Up @@ -115,7 +116,9 @@ public void consume(ParsableByteArray data, long timestamp, int sequenceNumber,
firstReceivedTimestamp = timestamp;
}

long timeUs = toSampleUs(startTimeOffsetUs, timestamp, firstReceivedTimestamp);
long timeUs =
toSampleTimeUs(
startTimeOffsetUs, timestamp, firstReceivedTimestamp, MEDIA_CLOCK_FREQUENCY);
trackOutput.sampleMetadata(
timeUs, bufferFlags, fragmentedSampleSizeBytes, /* offset= */ 0, /* cryptoData= */ null);
fragmentedSampleSizeBytes = 0;
Expand Down Expand Up @@ -287,15 +290,6 @@ private int writeStartCode() {
return bytesWritten;
}

private static long toSampleUs(
long startTimeOffsetUs, long rtpTimestamp, long firstReceivedRtpTimestamp) {
return startTimeOffsetUs
+ Util.scaleLargeTimestamp(
(rtpTimestamp - firstReceivedRtpTimestamp),
/* multiplier= */ C.MICROS_PER_SECOND,
/* divisor= */ MEDIA_CLOCK_FREQUENCY);
}

private static @C.BufferFlags int getBufferFlagsFromNalType(int nalType) {
return nalType == NAL_UNIT_TYPE_IDR ? C.BUFFER_FLAG_KEY_FRAME : 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.rtsp.reader;

import static com.google.android.exoplayer2.source.rtsp.reader.RtpReaderUtils.toSampleTimeUs;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;

Expand All @@ -38,7 +39,7 @@
/* package */ final class RtpH265Reader implements RtpPayloadReader {

private static final String TAG = "RtpH265Reader";
private static final long MEDIA_CLOCK_FREQUENCY = 90_000;
private static final int MEDIA_CLOCK_FREQUENCY = 90_000;
/** Offset of payload data within a FU payload. */
private static final int FU_PAYLOAD_OFFSET = 3;
/** Aggregation Packet. RFC7798 Section 4.4.2. */
Expand Down Expand Up @@ -111,7 +112,9 @@ public void consume(ParsableByteArray data, long timestamp, int sequenceNumber,
firstReceivedTimestamp = timestamp;
}

long timeUs = toSampleUs(startTimeOffsetUs, timestamp, firstReceivedTimestamp);
long timeUs =
toSampleTimeUs(
startTimeOffsetUs, timestamp, firstReceivedTimestamp, MEDIA_CLOCK_FREQUENCY);
trackOutput.sampleMetadata(
timeUs, bufferFlags, fragmentedSampleSizeBytes, /* offset= */ 0, /* cryptoData= */ null);
fragmentedSampleSizeBytes = 0;
Expand Down Expand Up @@ -254,15 +257,6 @@ private int writeStartCode() {
return bytesWritten;
}

private static long toSampleUs(
long startTimeOffsetUs, long rtpTimestamp, long firstReceivedRtpTimestamp) {
return startTimeOffsetUs
+ Util.scaleLargeTimestamp(
(rtpTimestamp - firstReceivedRtpTimestamp),
/* multiplier= */ C.MICROS_PER_SECOND,
/* divisor= */ MEDIA_CLOCK_FREQUENCY);
}

private static @C.BufferFlags int getBufferFlagsFromNalType(int nalType) {
return (nalType == NAL_IDR_W_RADL || nalType == NAL_IDR_N_LP) ? C.BUFFER_FLAG_KEY_FRAME : 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.rtsp.reader;

import static com.google.android.exoplayer2.source.rtsp.reader.RtpReaderUtils.toSampleTimeUs;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
import static com.google.android.exoplayer2.util.Util.castNonNull;

Expand All @@ -36,7 +37,7 @@
/* package */ final class RtpMpeg4Reader implements RtpPayloadReader {
private static final String TAG = "RtpMpeg4Reader";

private static final long MEDIA_CLOCK_FREQUENCY = 90_000;
private static final int MEDIA_CLOCK_FREQUENCY = 90_000;

/** VOP (Video Object Plane) unit type. */
private static final int I_VOP = 0;
Expand Down Expand Up @@ -102,7 +103,9 @@ public void consume(
firstReceivedTimestamp = timestamp;
}

long timeUs = toSampleUs(startTimeOffsetUs, timestamp, firstReceivedTimestamp);
long timeUs =
toSampleTimeUs(
startTimeOffsetUs, timestamp, firstReceivedTimestamp, MEDIA_CLOCK_FREQUENCY);
trackOutput.sampleMetadata(timeUs, bufferFlags, sampleLength, 0, null);
sampleLength = 0;
}
Expand Down Expand Up @@ -135,13 +138,4 @@ public void seek(long nextRtpTimestamp, long timeUs) {
}
return 0;
}

private static long toSampleUs(
long startTimeOffsetUs, long rtpTimestamp, long firstReceivedRtpTimestamp) {
return startTimeOffsetUs
+ Util.scaleLargeTimestamp(
(rtpTimestamp - firstReceivedRtpTimestamp),
/* multiplier= */ C.MICROS_PER_SECOND,
/* divisor= */ MEDIA_CLOCK_FREQUENCY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.rtsp.reader;

import static com.google.android.exoplayer2.source.rtsp.reader.RtpReaderUtils.toSampleTimeUs;
import static com.google.android.exoplayer2.util.Assertions.checkArgument;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;

Expand All @@ -38,7 +39,7 @@
/* package */ final class RtpOpusReader implements RtpPayloadReader {
private static final String TAG = "RtpOpusReader";
/* Opus uses a fixed 48KHz media clock RFC7845 Section 4. */
private static final long MEDIA_CLOCK_FREQUENCY = 48_000;
private static final int MEDIA_CLOCK_FREQUENCY = 48_000;

private final RtpPayloadFormat payloadFormat;

Expand Down Expand Up @@ -113,7 +114,9 @@ public void consume(
// sending opus data.
int size = data.bytesLeft();
trackOutput.sampleData(data, size);
long timeUs = toSampleTimeUs(startTimeOffsetUs, timestamp, firstReceivedTimestamp);
long timeUs =
toSampleTimeUs(
startTimeOffsetUs, timestamp, firstReceivedTimestamp, MEDIA_CLOCK_FREQUENCY);
trackOutput.sampleMetadata(
timeUs, C.BUFFER_FLAG_KEY_FRAME, size, /* offset*/ 0, /* cryptoData*/ null);
}
Expand Down Expand Up @@ -144,14 +147,4 @@ private static void validateOpusIdHeader(ParsableByteArray data) {
checkArgument(data.readUnsignedByte() == 1, "version number must always be 1");
data.setPosition(currPosition);
}

/** Returns the correct sample time from RTP timestamp, accounting for the OPUS sampling rate. */
private static long toSampleTimeUs(
long startTimeOffsetUs, long rtpTimestamp, long firstReceivedRtpTimestamp) {
return startTimeOffsetUs
+ Util.scaleLargeTimestamp(
rtpTimestamp - firstReceivedRtpTimestamp,
/* multiplier= */ C.MICROS_PER_SECOND,
/* divisor= */ MEDIA_CLOCK_FREQUENCY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.rtsp.reader;

import static com.google.android.exoplayer2.source.rtsp.reader.RtpReaderUtils.toSampleTimeUs;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;

import android.util.Log;
Expand Down Expand Up @@ -76,7 +77,8 @@ public void consume(
}

long sampleTimeUs =
toSampleUs(startTimeOffsetUs, timestamp, firstReceivedTimestamp, payloadFormat.clockRate);
toSampleTimeUs(
startTimeOffsetUs, timestamp, firstReceivedTimestamp, payloadFormat.clockRate);
int size = data.bytesLeft();
trackOutput.sampleData(data, size);
trackOutput.sampleMetadata(
Expand All @@ -91,14 +93,4 @@ public void seek(long nextRtpTimestamp, long timeUs) {
firstReceivedTimestamp = nextRtpTimestamp;
startTimeOffsetUs = timeUs;
}

/** Returns the correct sample time from RTP timestamp, accounting for the given clock rate. */
private static long toSampleUs(
long startTimeOffsetUs, long rtpTimestamp, long firstReceivedRtpTimestamp, int clockRate) {
return startTimeOffsetUs
+ Util.scaleLargeTimestamp(
rtpTimestamp - firstReceivedRtpTimestamp,
/* multiplier= */ C.MICROS_PER_SECOND,
/* divisor= */ clockRate);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.source.rtsp.reader;

import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Util;

/** Utility methods for {@link RtpPayloadReader}s. */
/* package */ class RtpReaderUtils {

/**
* Converts RTP timestamp and media frequency to sample presentation time, in microseconds
*
* @param startTimeOffsetUs The offset of the RTP timebase, in microseconds.
* @param rtpTimestamp The RTP timestamp to convert.
* @param firstReceivedRtpTimestamp The first received RTP timestamp.
* @param mediaFrequency The media frequency.
* @return The calculated sample presentation time, in microseconds.
*/
public static long toSampleTimeUs(
long startTimeOffsetUs,
long rtpTimestamp,
long firstReceivedRtpTimestamp,
int mediaFrequency) {
return startTimeOffsetUs
+ Util.scaleLargeTimestamp(
rtpTimestamp - firstReceivedRtpTimestamp,
/* multiplier= */ C.MICROS_PER_SECOND,
/* divisor= */ mediaFrequency);
}

private RtpReaderUtils() {}
}
Loading

0 comments on commit a1be6d6

Please sign in to comment.