mirror of
https://github.com/samsonjs/media.git
synced 2026-04-04 11:05:47 +00:00
Remove pipelining from MetadataRenderer
This reverts <unknown commit> Which was a temporary workaround for Issue: #1874 Also add a loop to ensure we process as many metadata items as applicable in each render() call. PiperOrigin-RevId: 366965504
This commit is contained in:
parent
9510ba4d91
commit
9e0e937c31
3 changed files with 65 additions and 67 deletions
|
|
@ -31,9 +31,7 @@ import com.google.android.exoplayer2.source.SampleStream.ReadDataResult;
|
|||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
||||
/**
|
||||
* A renderer for metadata.
|
||||
|
|
@ -42,24 +40,18 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
|||
|
||||
private static final String TAG = "MetadataRenderer";
|
||||
private static final int MSG_INVOKE_RENDERER = 0;
|
||||
// TODO: Holding multiple pending metadata objects is temporary mitigation against
|
||||
// https://github.com/google/ExoPlayer/issues/1874. It should be removed once this issue has been
|
||||
// addressed.
|
||||
private static final int MAX_PENDING_METADATA_COUNT = 5;
|
||||
|
||||
private final MetadataDecoderFactory decoderFactory;
|
||||
private final MetadataOutput output;
|
||||
@Nullable private final Handler outputHandler;
|
||||
private final MetadataInputBuffer buffer;
|
||||
private final @NullableType Metadata[] pendingMetadata;
|
||||
private final long[] pendingMetadataTimestamps;
|
||||
|
||||
private int pendingMetadataIndex;
|
||||
private int pendingMetadataCount;
|
||||
@Nullable private MetadataDecoder decoder;
|
||||
private boolean inputStreamEnded;
|
||||
private boolean outputStreamEnded;
|
||||
private long subsampleOffsetUs;
|
||||
private long pendingMetadataTimestampUs;
|
||||
@Nullable private Metadata pendingMetadata;
|
||||
|
||||
/**
|
||||
* @param output The output.
|
||||
|
|
@ -90,8 +82,7 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
|||
outputLooper == null ? null : Util.createHandler(outputLooper, /* callback= */ this);
|
||||
this.decoderFactory = Assertions.checkNotNull(decoderFactory);
|
||||
buffer = new MetadataInputBuffer();
|
||||
pendingMetadata = new Metadata[MAX_PENDING_METADATA_COUNT];
|
||||
pendingMetadataTimestamps = new long[MAX_PENDING_METADATA_COUNT];
|
||||
pendingMetadataTimestampUs = C.TIME_UNSET;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -117,51 +108,18 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
|||
|
||||
@Override
|
||||
protected void onPositionReset(long positionUs, boolean joining) {
|
||||
flushPendingMetadata();
|
||||
pendingMetadata = null;
|
||||
pendingMetadataTimestampUs = C.TIME_UNSET;
|
||||
inputStreamEnded = false;
|
||||
outputStreamEnded = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(long positionUs, long elapsedRealtimeUs) {
|
||||
if (!inputStreamEnded && pendingMetadataCount < MAX_PENDING_METADATA_COUNT) {
|
||||
buffer.clear();
|
||||
FormatHolder formatHolder = getFormatHolder();
|
||||
@ReadDataResult int result = readSource(formatHolder, buffer, /* readFlags= */ 0);
|
||||
if (result == C.RESULT_BUFFER_READ) {
|
||||
if (buffer.isEndOfStream()) {
|
||||
inputStreamEnded = true;
|
||||
} else {
|
||||
buffer.subsampleOffsetUs = subsampleOffsetUs;
|
||||
buffer.flip();
|
||||
@Nullable Metadata metadata = castNonNull(decoder).decode(buffer);
|
||||
if (metadata != null) {
|
||||
List<Metadata.Entry> entries = new ArrayList<>(metadata.length());
|
||||
decodeWrappedMetadata(metadata, entries);
|
||||
if (!entries.isEmpty()) {
|
||||
Metadata expandedMetadata = new Metadata(entries);
|
||||
int index =
|
||||
(pendingMetadataIndex + pendingMetadataCount) % MAX_PENDING_METADATA_COUNT;
|
||||
pendingMetadata[index] = expandedMetadata;
|
||||
pendingMetadataTimestamps[index] = buffer.timeUs;
|
||||
pendingMetadataCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (result == C.RESULT_FORMAT_READ) {
|
||||
subsampleOffsetUs = Assertions.checkNotNull(formatHolder.format).subsampleOffsetUs;
|
||||
}
|
||||
}
|
||||
|
||||
if (pendingMetadataCount > 0 && pendingMetadataTimestamps[pendingMetadataIndex] <= positionUs) {
|
||||
Metadata metadata = castNonNull(pendingMetadata[pendingMetadataIndex]);
|
||||
invokeRenderer(metadata);
|
||||
pendingMetadata[pendingMetadataIndex] = null;
|
||||
pendingMetadataIndex = (pendingMetadataIndex + 1) % MAX_PENDING_METADATA_COUNT;
|
||||
pendingMetadataCount--;
|
||||
}
|
||||
if (inputStreamEnded && pendingMetadataCount == 0) {
|
||||
outputStreamEnded = true;
|
||||
boolean working = true;
|
||||
while (working) {
|
||||
readMetadata();
|
||||
working = outputMetadata(positionUs);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -197,7 +155,8 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
|||
|
||||
@Override
|
||||
protected void onDisabled() {
|
||||
flushPendingMetadata();
|
||||
pendingMetadata = null;
|
||||
pendingMetadataTimestampUs = C.TIME_UNSET;
|
||||
decoder = null;
|
||||
}
|
||||
|
||||
|
|
@ -211,20 +170,6 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
|||
return true;
|
||||
}
|
||||
|
||||
private void invokeRenderer(Metadata metadata) {
|
||||
if (outputHandler != null) {
|
||||
outputHandler.obtainMessage(MSG_INVOKE_RENDERER, metadata).sendToTarget();
|
||||
} else {
|
||||
invokeRendererInternal(metadata);
|
||||
}
|
||||
}
|
||||
|
||||
private void flushPendingMetadata() {
|
||||
Arrays.fill(pendingMetadata, null);
|
||||
pendingMetadataIndex = 0;
|
||||
pendingMetadataCount = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
|
|
@ -237,6 +182,56 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
|||
}
|
||||
}
|
||||
|
||||
private void readMetadata() {
|
||||
if (!inputStreamEnded && pendingMetadata == null) {
|
||||
buffer.clear();
|
||||
FormatHolder formatHolder = getFormatHolder();
|
||||
@ReadDataResult int result = readSource(formatHolder, buffer, /* readFlags= */ 0);
|
||||
if (result == C.RESULT_BUFFER_READ) {
|
||||
if (buffer.isEndOfStream()) {
|
||||
inputStreamEnded = true;
|
||||
} else {
|
||||
buffer.subsampleOffsetUs = subsampleOffsetUs;
|
||||
buffer.flip();
|
||||
@Nullable Metadata metadata = castNonNull(decoder).decode(buffer);
|
||||
if (metadata != null) {
|
||||
List<Metadata.Entry> entries = new ArrayList<>(metadata.length());
|
||||
decodeWrappedMetadata(metadata, entries);
|
||||
if (!entries.isEmpty()) {
|
||||
Metadata expandedMetadata = new Metadata(entries);
|
||||
pendingMetadata = expandedMetadata;
|
||||
pendingMetadataTimestampUs = buffer.timeUs;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (result == C.RESULT_FORMAT_READ) {
|
||||
subsampleOffsetUs = Assertions.checkNotNull(formatHolder.format).subsampleOffsetUs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean outputMetadata(long positionUs) {
|
||||
boolean didOutput = false;
|
||||
if (pendingMetadata != null && pendingMetadataTimestampUs <= positionUs) {
|
||||
invokeRenderer(pendingMetadata);
|
||||
pendingMetadata = null;
|
||||
pendingMetadataTimestampUs = C.TIME_UNSET;
|
||||
didOutput = true;
|
||||
}
|
||||
if (inputStreamEnded && pendingMetadata == null) {
|
||||
outputStreamEnded = true;
|
||||
}
|
||||
return didOutput;
|
||||
}
|
||||
|
||||
private void invokeRenderer(Metadata metadata) {
|
||||
if (outputHandler != null) {
|
||||
outputHandler.obtainMessage(MSG_INVOKE_RENDERER, metadata).sendToTarget();
|
||||
} else {
|
||||
invokeRendererInternal(metadata);
|
||||
}
|
||||
}
|
||||
|
||||
private void invokeRendererInternal(Metadata metadata) {
|
||||
output.onMetadata(metadata);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ $ packager-linux \
|
|||
</AdaptationSet>
|
||||
<EventStream schemeIdUri="urn:mpeg:dash:event:callback:2015" timescale="1000" value="1">
|
||||
<Event presentationTime="100" duration="1000" id="0" messageData="" />
|
||||
<Event presentationTime="1000" duration="1000" id="1" messageData="" />
|
||||
<Event presentationTime="100" duration="1000" id="1" messageData="" />
|
||||
<Event presentationTime="1000" duration="1000" id="2" messageData="" />
|
||||
</EventStream>
|
||||
</Period>
|
||||
<Period id="1" start="PT1.022S">
|
||||
|
|
|
|||
|
|
@ -97,3 +97,5 @@ MetadataOutput:
|
|||
entry[0] = EMSG: scheme=urn:mpeg:dash:event:callback:2015, id=0, durationMs=1000, value=1
|
||||
Metadata[1]:
|
||||
entry[0] = EMSG: scheme=urn:mpeg:dash:event:callback:2015, id=1, durationMs=1000, value=1
|
||||
Metadata[2]:
|
||||
entry[0] = EMSG: scheme=urn:mpeg:dash:event:callback:2015, id=2, durationMs=1000, value=1
|
||||
|
|
|
|||
Loading…
Reference in a new issue