Commit 07a1998a by tianyifeng Committed by Tofunmi Adigun-Hameed

Defer outputting the metadata sample when TimestampAdjuster isn't initialized

The sample timestamp carried by the emsg box can have a significant delta when comparing to the earliest presentation timestamp of the segment. Using this timestamp to intialize the timestamp offset in TimestampAdjuster will cause the media sample to have a wrong adjusted timestamp. So we should defer adjusting the metadata sample timestamp until the TimestampAdjuster is initialized with a real media sample.

PiperOrigin-RevId: 538172841
(cherry picked from commit 08c189e768d77e9e2a9665b23fa384e776f9678b)
parent 72983cb7
...@@ -105,14 +105,13 @@ public final class TimestampAdjuster { ...@@ -105,14 +105,13 @@ public final class TimestampAdjuster {
public synchronized void sharedInitializeOrWait(boolean canInitialize, long nextSampleTimestampUs) public synchronized void sharedInitializeOrWait(boolean canInitialize, long nextSampleTimestampUs)
throws InterruptedException { throws InterruptedException {
Assertions.checkState(firstSampleTimestampUs == MODE_SHARED); Assertions.checkState(firstSampleTimestampUs == MODE_SHARED);
if (timestampOffsetUs != C.TIME_UNSET) { if (isInitialized()) {
// Already initialized.
return; return;
} else if (canInitialize) { } else if (canInitialize) {
this.nextSampleTimestampUs.set(nextSampleTimestampUs); this.nextSampleTimestampUs.set(nextSampleTimestampUs);
} else { } else {
// Wait for another calling thread to complete initialization. // Wait for another calling thread to complete initialization.
while (timestampOffsetUs == C.TIME_UNSET) { while (!isInitialized()) {
wait(); wait();
} }
} }
...@@ -194,7 +193,7 @@ public final class TimestampAdjuster { ...@@ -194,7 +193,7 @@ public final class TimestampAdjuster {
if (timeUs == C.TIME_UNSET) { if (timeUs == C.TIME_UNSET) {
return C.TIME_UNSET; return C.TIME_UNSET;
} }
if (timestampOffsetUs == C.TIME_UNSET) { if (!isInitialized()) {
long desiredSampleTimestampUs = long desiredSampleTimestampUs =
firstSampleTimestampUs == MODE_SHARED firstSampleTimestampUs == MODE_SHARED
? Assertions.checkNotNull(nextSampleTimestampUs.get()) ? Assertions.checkNotNull(nextSampleTimestampUs.get())
...@@ -207,6 +206,11 @@ public final class TimestampAdjuster { ...@@ -207,6 +206,11 @@ public final class TimestampAdjuster {
return timeUs + timestampOffsetUs; return timeUs + timestampOffsetUs;
} }
/** Returns whether the instance is initialized with a timestamp offset. */
public synchronized boolean isInitialized() {
return timestampOffsetUs != C.TIME_UNSET;
}
/** /**
* Converts a 90 kHz clock timestamp to a timestamp in microseconds. * Converts a 90 kHz clock timestamp to a timestamp in microseconds.
* *
......
...@@ -681,6 +681,13 @@ public class FragmentedMp4Extractor implements Extractor { ...@@ -681,6 +681,13 @@ public class FragmentedMp4Extractor implements Extractor {
pendingMetadataSampleInfos.addLast( pendingMetadataSampleInfos.addLast(
new MetadataSampleInfo(sampleTimeUs, /* sampleTimeIsRelative= */ false, sampleSize)); new MetadataSampleInfo(sampleTimeUs, /* sampleTimeIsRelative= */ false, sampleSize));
pendingMetadataSampleBytes += sampleSize; pendingMetadataSampleBytes += sampleSize;
} else if (timestampAdjuster != null && !timestampAdjuster.isInitialized()) {
// We also need to defer outputting metadata if the timestampAdjuster is not initialized,
// else we will set a wrong timestampOffsetUs in timestampAdjuster. See:
// https://github.com/androidx/media/issues/356.
pendingMetadataSampleInfos.addLast(
new MetadataSampleInfo(sampleTimeUs, /* sampleTimeIsRelative= */ false, sampleSize));
pendingMetadataSampleBytes += sampleSize;
} else { } else {
// We can output the sample metadata immediately. // We can output the sample metadata immediately.
if (timestampAdjuster != null) { if (timestampAdjuster != null) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment