From 5e2c7d967a74fe0ce67b9c57bb391c40935566d1 Mon Sep 17 00:00:00 2001 From: aquilescanta Date: Mon, 18 Sep 2017 05:44:31 -0700 Subject: [PATCH] Fix 2 CEA decoder bugs 1- Avoid dropped buffers by using a PriorityQueue instead of a set. 2- Process the end of stream after non-EOS buffers. Issue:#3250 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=169077365 --- .../exoplayer2/text/SubtitleInputBuffer.java | 3 +++ .../android/exoplayer2/text/TextRenderer.java | 8 ++++---- .../android/exoplayer2/text/cea/CeaDecoder.java | 14 ++++++-------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleInputBuffer.java b/library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleInputBuffer.java index 28e67e8623..4b3b61bddf 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleInputBuffer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleInputBuffer.java @@ -37,6 +37,9 @@ public final class SubtitleInputBuffer extends DecoderInputBuffer @Override public int compareTo(@NonNull SubtitleInputBuffer other) { + if (isEndOfStream() != other.isEndOfStream()) { + return isEndOfStream() ? 1 : -1; + } long delta = timeUs - other.timeUs; if (delta == 0) { return 0; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java index c3dc2383ef..c6d7f6f163 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java @@ -37,7 +37,7 @@ import java.util.List; *

* {@link Subtitle}s are decoded from sample data using {@link SubtitleDecoder} instances obtained * from a {@link SubtitleDecoderFactory}. The actual rendering of the subtitle {@link Cue}s is - * delegated to an {@link TextOutput}. + * delegated to a {@link TextOutput}. */ public final class TextRenderer extends BaseRenderer implements Callback { @@ -291,9 +291,9 @@ public final class TextRenderer extends BaseRenderer implements Callback { } private long getNextEventTime() { - return ((nextSubtitleEventIndex == C.INDEX_UNSET) - || (nextSubtitleEventIndex >= subtitle.getEventTimeCount())) ? Long.MAX_VALUE - : (subtitle.getEventTime(nextSubtitleEventIndex)); + return nextSubtitleEventIndex == C.INDEX_UNSET + || nextSubtitleEventIndex >= subtitle.getEventTimeCount() + ? Long.MAX_VALUE : subtitle.getEventTime(nextSubtitleEventIndex); } private void updateOutput(List cues) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/cea/CeaDecoder.java b/library/core/src/main/java/com/google/android/exoplayer2/text/cea/CeaDecoder.java index fac0982e65..bb13a7d143 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/cea/CeaDecoder.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/cea/CeaDecoder.java @@ -24,7 +24,7 @@ import com.google.android.exoplayer2.text.SubtitleInputBuffer; import com.google.android.exoplayer2.text.SubtitleOutputBuffer; import com.google.android.exoplayer2.util.Assertions; import java.util.LinkedList; -import java.util.TreeSet; +import java.util.PriorityQueue; /** * Base class for subtitle parsers for CEA captions. @@ -36,7 +36,7 @@ import java.util.TreeSet; private final LinkedList availableInputBuffers; private final LinkedList availableOutputBuffers; - private final TreeSet queuedInputBuffers; + private final PriorityQueue queuedInputBuffers; private SubtitleInputBuffer dequeuedInputBuffer; private long playbackPositionUs; @@ -50,7 +50,7 @@ import java.util.TreeSet; for (int i = 0; i < NUM_OUTPUT_BUFFERS; i++) { availableOutputBuffers.add(new CeaOutputBuffer(this)); } - queuedInputBuffers = new TreeSet<>(); + queuedInputBuffers = new PriorityQueue<>(); } @Override @@ -73,7 +73,6 @@ import java.util.TreeSet; @Override public void queueInputBuffer(SubtitleInputBuffer inputBuffer) throws SubtitleDecoderException { - Assertions.checkArgument(inputBuffer != null); Assertions.checkArgument(inputBuffer == dequeuedInputBuffer); if (inputBuffer.isDecodeOnly()) { // We can drop this buffer early (i.e. before it would be decoded) as the CEA formats allow @@ -90,13 +89,12 @@ import java.util.TreeSet; if (availableOutputBuffers.isEmpty()) { return null; } - // iterate through all available input buffers whose timestamps are less than or equal // to the current playback position; processing input buffers for future content should // be deferred until they would be applicable while (!queuedInputBuffers.isEmpty() - && queuedInputBuffers.first().timeUs <= playbackPositionUs) { - SubtitleInputBuffer inputBuffer = queuedInputBuffers.pollFirst(); + && queuedInputBuffers.peek().timeUs <= playbackPositionUs) { + SubtitleInputBuffer inputBuffer = queuedInputBuffers.poll(); // If the input buffer indicates we've reached the end of the stream, we can // return immediately with an output buffer propagating that @@ -142,7 +140,7 @@ import java.util.TreeSet; public void flush() { playbackPositionUs = 0; while (!queuedInputBuffers.isEmpty()) { - releaseInputBuffer(queuedInputBuffers.pollFirst()); + releaseInputBuffer(queuedInputBuffers.poll()); } if (dequeuedInputBuffer != null) { releaseInputBuffer(dequeuedInputBuffer);