From 961f01a850f2879d5eda461f4f431e04347a5e34 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 | 6 +++--- .../android/exoplayer2/text/cea/CeaDecoder.java | 14 ++++++-------- 3 files changed, 12 insertions(+), 11 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 28e67e8623a..4b3b61bddf3 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 SubtitleInputBuffer() { @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 1820d43e750..700fc0cb4b1 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 @@ -294,9 +294,9 @@ private void replaceDecoder() { } 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 fac0982e659..bb13a7d1432 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.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 @@ 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 @@ public CeaDecoder() { 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 @@ public SubtitleInputBuffer dequeueInputBuffer() throws SubtitleDecoderException @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 @@ public SubtitleOutputBuffer dequeueOutputBuffer() throws SubtitleDecoderExceptio 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 @@ protected void releaseOutputBuffer(SubtitleOutputBuffer outputBuffer) { public void flush() { playbackPositionUs = 0; while (!queuedInputBuffers.isEmpty()) { - releaseInputBuffer(queuedInputBuffers.pollFirst()); + releaseInputBuffer(queuedInputBuffers.poll()); } if (dequeuedInputBuffer != null) { releaseInputBuffer(dequeuedInputBuffer);