Ensure only timestamp adjustment masters set first sample timestamps
Without this, it is possible that a non timestamp master instances the adjuster with its own chunk start time. When chunks are not aligned, this breaks adjustment. Issue:#2424 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=149764488
This commit is contained in:
parent
15aad266b6
commit
952bde700b
@ -383,7 +383,8 @@ public final class TsExtractor implements Extractor {
|
||||
if (mode == MODE_SINGLE_PMT || mode == MODE_HLS || remainingPmts == 1) {
|
||||
timestampAdjuster = timestampAdjusters.get(0);
|
||||
} else {
|
||||
timestampAdjuster = new TimestampAdjuster(timestampAdjusters.get(0).firstSampleTimestampUs);
|
||||
timestampAdjuster = new TimestampAdjuster(
|
||||
timestampAdjusters.get(0).getFirstSampleTimestampUs());
|
||||
timestampAdjusters.add(timestampAdjuster);
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,9 @@ public final class SpliceInfoDecoder implements MetadataDecoder {
|
||||
case TYPE_PRIVATE_COMMAND:
|
||||
command = PrivateCommand.parseFromSection(sectionData, spliceCommandLength, ptsAdjustment);
|
||||
break;
|
||||
default:
|
||||
// Do nothing.
|
||||
break;
|
||||
}
|
||||
return command == null ? new Metadata() : new Metadata(command);
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ import java.util.Locale;
|
||||
int discontinuitySequence = mediaPlaylist.discontinuitySequence
|
||||
+ segment.relativeDiscontinuitySequence;
|
||||
TimestampAdjuster timestampAdjuster = timestampAdjusterProvider.getAdjuster(
|
||||
discontinuitySequence, startTimeUs);
|
||||
discontinuitySequence);
|
||||
|
||||
// Configure the data source and spec for the chunk.
|
||||
Uri chunkUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, segment.url);
|
||||
|
@ -242,6 +242,9 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
}
|
||||
if (!isMasterTimestampSource) {
|
||||
timestampAdjuster.waitUntilInitialized();
|
||||
} else if (timestampAdjuster.getFirstSampleTimestampUs() == TimestampAdjuster.DO_NOT_OFFSET) {
|
||||
// We're the master and we haven't set the desired first sample timestamp yet.
|
||||
timestampAdjuster.setFirstSampleTimestampUs(startTimeUs);
|
||||
}
|
||||
try {
|
||||
ExtractorInput input = new DefaultExtractorInput(dataSource,
|
||||
|
@ -36,13 +36,12 @@ public final class TimestampAdjusterProvider {
|
||||
* a chunk with a given discontinuity sequence.
|
||||
*
|
||||
* @param discontinuitySequence The chunk's discontinuity sequence.
|
||||
* @param startTimeUs The chunk's start time.
|
||||
* @return A {@link TimestampAdjuster}.
|
||||
*/
|
||||
public TimestampAdjuster getAdjuster(int discontinuitySequence, long startTimeUs) {
|
||||
public TimestampAdjuster getAdjuster(int discontinuitySequence) {
|
||||
TimestampAdjuster adjuster = timestampAdjusters.get(discontinuitySequence);
|
||||
if (adjuster == null) {
|
||||
adjuster = new TimestampAdjuster(startTimeUs);
|
||||
adjuster = new TimestampAdjuster(TimestampAdjuster.DO_NOT_OFFSET);
|
||||
timestampAdjusters.put(discontinuitySequence, adjuster);
|
||||
}
|
||||
return adjuster;
|
||||
|
@ -34,21 +34,39 @@ public final class TimestampAdjuster {
|
||||
*/
|
||||
private static final long MAX_PTS_PLUS_ONE = 0x200000000L;
|
||||
|
||||
public final long firstSampleTimestampUs;
|
||||
|
||||
private long firstSampleTimestampUs;
|
||||
private long timestampOffsetUs;
|
||||
|
||||
// Volatile to allow isInitialized to be called on a different thread to adjustSampleTimestamp.
|
||||
private volatile long lastSampleTimestamp;
|
||||
|
||||
/**
|
||||
* @param firstSampleTimestampUs The desired result of the first call to
|
||||
* {@link #adjustSampleTimestamp(long)}, or {@link #DO_NOT_OFFSET} if presentation timestamps
|
||||
* should not be offset.
|
||||
* @param firstSampleTimestampUs See {@link #setFirstSampleTimestampUs(long)}.
|
||||
*/
|
||||
public TimestampAdjuster(long firstSampleTimestampUs) {
|
||||
this.firstSampleTimestampUs = firstSampleTimestampUs;
|
||||
lastSampleTimestamp = C.TIME_UNSET;
|
||||
setFirstSampleTimestampUs(firstSampleTimestampUs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the desired result of the first call to {@link #adjustSampleTimestamp(long)}. Can only be
|
||||
* called before any timestamps have been adjusted.
|
||||
*
|
||||
* @param firstSampleTimestampUs The first adjusted sample timestamp in microseconds, or
|
||||
* {@link #DO_NOT_OFFSET} if presentation timestamps should not be offset.
|
||||
*/
|
||||
public synchronized void setFirstSampleTimestampUs(long firstSampleTimestampUs) {
|
||||
Assertions.checkState(lastSampleTimestamp == C.TIME_UNSET);
|
||||
this.firstSampleTimestampUs = firstSampleTimestampUs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first adjusted sample timestamp in microseconds.
|
||||
*
|
||||
* @return The first adjusted sample timestamp in microseconds.
|
||||
*/
|
||||
public long getFirstSampleTimestampUs() {
|
||||
return firstSampleTimestampUs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user