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
This commit is contained in:
parent
08e7158be5
commit
f4bf376e89
@ -14,6 +14,9 @@
|
||||
* Parse EXIF rotation data for image inputs.
|
||||
* Track Selection:
|
||||
* Extractors:
|
||||
* FMP4: Fix issue where `TimestampAdjuster` initializes a wrong timestamp
|
||||
offset with metadata sample time from emsg atom
|
||||
([#356](https://github.com/androidx/media/issues/356)).
|
||||
* Audio:
|
||||
* Audio Offload:
|
||||
* Add `AudioSink.getFormatOffloadSupport(Format)` that retrieves level of
|
||||
|
@ -106,14 +106,13 @@ public final class TimestampAdjuster {
|
||||
public synchronized void sharedInitializeOrWait(boolean canInitialize, long nextSampleTimestampUs)
|
||||
throws InterruptedException {
|
||||
Assertions.checkState(firstSampleTimestampUs == MODE_SHARED);
|
||||
if (timestampOffsetUs != C.TIME_UNSET) {
|
||||
// Already initialized.
|
||||
if (isInitialized()) {
|
||||
return;
|
||||
} else if (canInitialize) {
|
||||
this.nextSampleTimestampUs.set(nextSampleTimestampUs);
|
||||
} else {
|
||||
// Wait for another calling thread to complete initialization.
|
||||
while (timestampOffsetUs == C.TIME_UNSET) {
|
||||
while (!isInitialized()) {
|
||||
wait();
|
||||
}
|
||||
}
|
||||
@ -195,7 +194,7 @@ public final class TimestampAdjuster {
|
||||
if (timeUs == C.TIME_UNSET) {
|
||||
return C.TIME_UNSET;
|
||||
}
|
||||
if (timestampOffsetUs == C.TIME_UNSET) {
|
||||
if (!isInitialized()) {
|
||||
long desiredSampleTimestampUs =
|
||||
firstSampleTimestampUs == MODE_SHARED
|
||||
? Assertions.checkNotNull(nextSampleTimestampUs.get())
|
||||
@ -208,6 +207,11 @@ public final class TimestampAdjuster {
|
||||
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.
|
||||
*
|
||||
|
@ -683,6 +683,13 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||
pendingMetadataSampleInfos.addLast(
|
||||
new MetadataSampleInfo(sampleTimeUs, /* sampleTimeIsRelative= */ false, 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 {
|
||||
// We can output the sample metadata immediately.
|
||||
if (timestampAdjuster != null) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user