Skip to content

Commit

Permalink
FMP4: Fix output of mixed v0 and v1 emsg samples
Browse files Browse the repository at this point in the history
Issue: #9996
#minor-release
PiperOrigin-RevId: 430773329
  • Loading branch information
ojw28 authored and icbaker committed Mar 1, 2022
1 parent 4d51880 commit 1bc4ba2
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 14 deletions.
5 changes: 4 additions & 1 deletion RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
* Flatten `TrackSelectionOverrides` class into `TrackSelectionParameters`,
and promote `TrackSelectionOverride` to a top level class.
* Extractors:
* Opus DiscardPadding in Matroska files.
* Matroska: Parse `DiscardPadding` for Opus tracks.
* FMP4: Fix issue where emsg sample metadata could be output in the wrong
order for streams containing both v0 and v1 emsg atoms
([#9996](https://github.com/google/ExoPlayer/issues/9996)).
* RTSP:
* Add RTP reader for HEVC
([#36](https://github.com/androidx/media/pull/36))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -666,14 +666,23 @@ private void onEmsgLeafAtomRead(ParsableByteArray atom) {
emsgTrackOutput.sampleData(encodedEventMessage, sampleSize);
}

// Output the sample metadata. This is made a little complicated because emsg-v0 atoms
// have presentation time *delta* while v1 atoms have absolute presentation time.
// Output the sample metadata.
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(
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;
} else {
// We can output the sample metadata immediately.
if (timestampAdjuster != null) {
sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(sampleTimeUs);
}
Expand Down Expand Up @@ -1459,19 +1468,30 @@ private boolean readSample(ExtractorInput input) throws IOException {
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) {
while (!pendingMetadataSampleInfos.isEmpty()) {
MetadataSampleInfo sampleInfo = pendingMetadataSampleInfos.removeFirst();
pendingMetadataSampleBytes -= sampleInfo.size;
long metadataTimeUs = sampleTimeUs + sampleInfo.presentationTimeDeltaUs;
MetadataSampleInfo metadataSampleInfo = pendingMetadataSampleInfos.removeFirst();
pendingMetadataSampleBytes -= metadataSampleInfo.size;
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) {
metadataTimeUs = timestampAdjuster.adjustSampleTimestamp(metadataTimeUs);
metadataSampleTimeUs = timestampAdjuster.adjustSampleTimestamp(metadataSampleTimeUs);
}
for (TrackOutput emsgTrackOutput : emsgTrackOutputs) {
emsgTrackOutput.sampleMetadata(
metadataTimeUs,
metadataSampleTimeUs,
C.BUFFER_FLAG_KEY_FRAME,
sampleInfo.size,
metadataSampleInfo.size,
pendingMetadataSampleBytes,
null);
}
Expand Down Expand Up @@ -1577,11 +1597,13 @@ private static boolean shouldParseContainerAtom(int atom) {
/** Holds data corresponding to a metadata sample. */
private static final class MetadataSampleInfo {

public final long presentationTimeDeltaUs;
public final long sampleTimeUs;
public final boolean sampleTimeIsRelative;
public final int size;

public MetadataSampleInfo(long presentationTimeDeltaUs, int size) {
this.presentationTimeDeltaUs = presentationTimeDeltaUs;
public MetadataSampleInfo(long sampleTimeUs, boolean sampleTimeIsRelative, int size) {
this.sampleTimeUs = sampleTimeUs;
this.sampleTimeIsRelative = sampleTimeIsRelative;
this.size = size;
}
}
Expand Down

0 comments on commit 1bc4ba2

Please sign in to comment.