mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
FMP4: Fix output of mixed v0 and v1 emsg samples
Issue: google/ExoPlayer#9996 #minor-release PiperOrigin-RevId: 430773329 (cherry picked from commit 5a304fdbd9bc8af8229b1a9cddc79f359fe8e215)
This commit is contained in:
parent
7125a3361b
commit
d10700456d
@ -666,14 +666,23 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
emsgTrackOutput.sampleData(encodedEventMessage, sampleSize);
|
emsgTrackOutput.sampleData(encodedEventMessage, sampleSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output the sample metadata. This is made a little complicated because emsg-v0 atoms
|
// Output the sample metadata.
|
||||||
// have presentation time *delta* while v1 atoms have absolute presentation time.
|
|
||||||
if (sampleTimeUs == C.TIME_UNSET) {
|
if (sampleTimeUs == C.TIME_UNSET) {
|
||||||
// We need the first sample timestamp in the segment before we can output the metadata.
|
// We're processing a v0 emsg atom, which contains a presentation time delta, and cannot yet
|
||||||
|
// calculate its absolute sample timestamp. Defer outputting the metadata until we can.
|
||||||
pendingMetadataSampleInfos.addLast(
|
pendingMetadataSampleInfos.addLast(
|
||||||
new MetadataSampleInfo(presentationTimeDeltaUs, sampleSize));
|
new MetadataSampleInfo(
|
||||||
|
presentationTimeDeltaUs, /* sampleTimeIsRelative= */ true, sampleSize));
|
||||||
|
pendingMetadataSampleBytes += sampleSize;
|
||||||
|
} else if (!pendingMetadataSampleInfos.isEmpty()) {
|
||||||
|
// We also need to defer outputting metadata if pendingMetadataSampleInfos is non-empty, else
|
||||||
|
// we will output metadata for samples in the wrong order. See:
|
||||||
|
// https://github.com/google/ExoPlayer/issues/9996.
|
||||||
|
pendingMetadataSampleInfos.addLast(
|
||||||
|
new MetadataSampleInfo(sampleTimeUs, /* sampleTimeIsRelative= */ false, sampleSize));
|
||||||
pendingMetadataSampleBytes += sampleSize;
|
pendingMetadataSampleBytes += sampleSize;
|
||||||
} else {
|
} else {
|
||||||
|
// We can output the sample metadata immediately.
|
||||||
if (timestampAdjuster != null) {
|
if (timestampAdjuster != null) {
|
||||||
sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(sampleTimeUs);
|
sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(sampleTimeUs);
|
||||||
}
|
}
|
||||||
@ -1459,19 +1468,30 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called immediately after outputting a non-metadata sample, to output any pending metadata
|
||||||
|
* samples.
|
||||||
|
*
|
||||||
|
* @param sampleTimeUs The timestamp of the non-metadata sample that was just output.
|
||||||
|
*/
|
||||||
private void outputPendingMetadataSamples(long sampleTimeUs) {
|
private void outputPendingMetadataSamples(long sampleTimeUs) {
|
||||||
while (!pendingMetadataSampleInfos.isEmpty()) {
|
while (!pendingMetadataSampleInfos.isEmpty()) {
|
||||||
MetadataSampleInfo sampleInfo = pendingMetadataSampleInfos.removeFirst();
|
MetadataSampleInfo metadataSampleInfo = pendingMetadataSampleInfos.removeFirst();
|
||||||
pendingMetadataSampleBytes -= sampleInfo.size;
|
pendingMetadataSampleBytes -= metadataSampleInfo.size;
|
||||||
long metadataTimeUs = sampleTimeUs + sampleInfo.presentationTimeDeltaUs;
|
long metadataSampleTimeUs = metadataSampleInfo.sampleTimeUs;
|
||||||
|
if (metadataSampleInfo.sampleTimeIsRelative) {
|
||||||
|
// The metadata sample timestamp is relative to the timestamp of the non-metadata sample
|
||||||
|
// that was just output. Make it absolute.
|
||||||
|
metadataSampleTimeUs += sampleTimeUs;
|
||||||
|
}
|
||||||
if (timestampAdjuster != null) {
|
if (timestampAdjuster != null) {
|
||||||
metadataTimeUs = timestampAdjuster.adjustSampleTimestamp(metadataTimeUs);
|
metadataSampleTimeUs = timestampAdjuster.adjustSampleTimestamp(metadataSampleTimeUs);
|
||||||
}
|
}
|
||||||
for (TrackOutput emsgTrackOutput : emsgTrackOutputs) {
|
for (TrackOutput emsgTrackOutput : emsgTrackOutputs) {
|
||||||
emsgTrackOutput.sampleMetadata(
|
emsgTrackOutput.sampleMetadata(
|
||||||
metadataTimeUs,
|
metadataSampleTimeUs,
|
||||||
C.BUFFER_FLAG_KEY_FRAME,
|
C.BUFFER_FLAG_KEY_FRAME,
|
||||||
sampleInfo.size,
|
metadataSampleInfo.size,
|
||||||
pendingMetadataSampleBytes,
|
pendingMetadataSampleBytes,
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
@ -1577,11 +1597,13 @@ public class FragmentedMp4Extractor implements Extractor {
|
|||||||
/** Holds data corresponding to a metadata sample. */
|
/** Holds data corresponding to a metadata sample. */
|
||||||
private static final class MetadataSampleInfo {
|
private static final class MetadataSampleInfo {
|
||||||
|
|
||||||
public final long presentationTimeDeltaUs;
|
public final long sampleTimeUs;
|
||||||
|
public final boolean sampleTimeIsRelative;
|
||||||
public final int size;
|
public final int size;
|
||||||
|
|
||||||
public MetadataSampleInfo(long presentationTimeDeltaUs, int size) {
|
public MetadataSampleInfo(long sampleTimeUs, boolean sampleTimeIsRelative, int size) {
|
||||||
this.presentationTimeDeltaUs = presentationTimeDeltaUs;
|
this.sampleTimeUs = sampleTimeUs;
|
||||||
|
this.sampleTimeIsRelative = sampleTimeIsRelative;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user