mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Use stable order for subtitle buffers with identical timestamps
Issue: #3782 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=185673731
This commit is contained in:
parent
8dad8fde78
commit
93e6813f76
4 changed files with 49 additions and 69 deletions
|
|
@ -76,8 +76,12 @@
|
||||||
* Support resampling 24-bit and 32-bit integer to 32-bit float for high
|
* Support resampling 24-bit and 32-bit integer to 32-bit float for high
|
||||||
resolution output in `DefaultAudioSink`
|
resolution output in `DefaultAudioSink`
|
||||||
([#3635](https://github.com/google/ExoPlayer/pull/3635)).
|
([#3635](https://github.com/google/ExoPlayer/pull/3635)).
|
||||||
* Captions: Initial support for PGS subtitles
|
* Captions:
|
||||||
([#3008](https://github.com/google/ExoPlayer/issues/3008)).
|
* Initial support for PGS subtitles
|
||||||
|
([#3008](https://github.com/google/ExoPlayer/issues/3008)).
|
||||||
|
* Fix issue handling CEA-608 captions where multiple buffers have the same
|
||||||
|
presentation timestamp
|
||||||
|
([#3782](https://github.com/google/ExoPlayer/issues/3782)).
|
||||||
* CacheDataSource: Check periodically if it's possible to read from/write to
|
* CacheDataSource: Check periodically if it's possible to read from/write to
|
||||||
cache after deciding to bypass cache.
|
cache after deciding to bypass cache.
|
||||||
* IMA extension:
|
* IMA extension:
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.text;
|
package com.google.android.exoplayer2.text;
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
|
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
|
||||||
|
|
||||||
/**
|
/** A {@link DecoderInputBuffer} for a {@link SubtitleDecoder}. */
|
||||||
* A {@link DecoderInputBuffer} for a {@link SubtitleDecoder}.
|
public class SubtitleInputBuffer extends DecoderInputBuffer {
|
||||||
*/
|
|
||||||
public final class SubtitleInputBuffer extends DecoderInputBuffer
|
|
||||||
implements Comparable<SubtitleInputBuffer> {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An offset that must be added to the subtitle's event times after it's been decoded, or
|
* An offset that must be added to the subtitle's event times after it's been decoded, or
|
||||||
|
|
@ -35,16 +31,4 @@ public final class SubtitleInputBuffer extends DecoderInputBuffer
|
||||||
super(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
|
super(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@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;
|
|
||||||
}
|
|
||||||
return delta > 0 ? 1 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.text.cea;
|
package com.google.android.exoplayer2.text.cea;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.text.Subtitle;
|
import com.google.android.exoplayer2.text.Subtitle;
|
||||||
|
|
@ -34,21 +35,22 @@ import java.util.PriorityQueue;
|
||||||
private static final int NUM_INPUT_BUFFERS = 10;
|
private static final int NUM_INPUT_BUFFERS = 10;
|
||||||
private static final int NUM_OUTPUT_BUFFERS = 2;
|
private static final int NUM_OUTPUT_BUFFERS = 2;
|
||||||
|
|
||||||
private final LinkedList<SubtitleInputBuffer> availableInputBuffers;
|
private final LinkedList<CeaInputBuffer> availableInputBuffers;
|
||||||
private final LinkedList<SubtitleOutputBuffer> availableOutputBuffers;
|
private final LinkedList<SubtitleOutputBuffer> availableOutputBuffers;
|
||||||
private final PriorityQueue<SubtitleInputBuffer> queuedInputBuffers;
|
private final PriorityQueue<CeaInputBuffer> queuedInputBuffers;
|
||||||
|
|
||||||
private SubtitleInputBuffer dequeuedInputBuffer;
|
private CeaInputBuffer dequeuedInputBuffer;
|
||||||
private long playbackPositionUs;
|
private long playbackPositionUs;
|
||||||
|
private long queuedInputBufferCount;
|
||||||
|
|
||||||
public CeaDecoder() {
|
public CeaDecoder() {
|
||||||
availableInputBuffers = new LinkedList<>();
|
availableInputBuffers = new LinkedList<>();
|
||||||
for (int i = 0; i < NUM_INPUT_BUFFERS; i++) {
|
for (int i = 0; i < NUM_INPUT_BUFFERS; i++) {
|
||||||
availableInputBuffers.add(new SubtitleInputBuffer());
|
availableInputBuffers.add(new CeaInputBuffer());
|
||||||
}
|
}
|
||||||
availableOutputBuffers = new LinkedList<>();
|
availableOutputBuffers = new LinkedList<>();
|
||||||
for (int i = 0; i < NUM_OUTPUT_BUFFERS; i++) {
|
for (int i = 0; i < NUM_OUTPUT_BUFFERS; i++) {
|
||||||
availableOutputBuffers.add(new CeaOutputBuffer(this));
|
availableOutputBuffers.add(new CeaOutputBuffer());
|
||||||
}
|
}
|
||||||
queuedInputBuffers = new PriorityQueue<>();
|
queuedInputBuffers = new PriorityQueue<>();
|
||||||
}
|
}
|
||||||
|
|
@ -77,9 +79,10 @@ import java.util.PriorityQueue;
|
||||||
if (inputBuffer.isDecodeOnly()) {
|
if (inputBuffer.isDecodeOnly()) {
|
||||||
// We can drop this buffer early (i.e. before it would be decoded) as the CEA formats allow
|
// We can drop this buffer early (i.e. before it would be decoded) as the CEA formats allow
|
||||||
// for decoding to begin mid-stream.
|
// for decoding to begin mid-stream.
|
||||||
releaseInputBuffer(inputBuffer);
|
releaseInputBuffer(dequeuedInputBuffer);
|
||||||
} else {
|
} else {
|
||||||
queuedInputBuffers.add(inputBuffer);
|
dequeuedInputBuffer.queuedInputBufferCount = queuedInputBufferCount++;
|
||||||
|
queuedInputBuffers.add(dequeuedInputBuffer);
|
||||||
}
|
}
|
||||||
dequeuedInputBuffer = null;
|
dequeuedInputBuffer = null;
|
||||||
}
|
}
|
||||||
|
|
@ -94,7 +97,7 @@ import java.util.PriorityQueue;
|
||||||
// be deferred until they would be applicable
|
// be deferred until they would be applicable
|
||||||
while (!queuedInputBuffers.isEmpty()
|
while (!queuedInputBuffers.isEmpty()
|
||||||
&& queuedInputBuffers.peek().timeUs <= playbackPositionUs) {
|
&& queuedInputBuffers.peek().timeUs <= playbackPositionUs) {
|
||||||
SubtitleInputBuffer inputBuffer = queuedInputBuffers.poll();
|
CeaInputBuffer inputBuffer = queuedInputBuffers.poll();
|
||||||
|
|
||||||
// If the input buffer indicates we've reached the end of the stream, we can
|
// If the input buffer indicates we've reached the end of the stream, we can
|
||||||
// return immediately with an output buffer propagating that
|
// return immediately with an output buffer propagating that
|
||||||
|
|
@ -126,7 +129,7 @@ import java.util.PriorityQueue;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void releaseInputBuffer(SubtitleInputBuffer inputBuffer) {
|
private void releaseInputBuffer(CeaInputBuffer inputBuffer) {
|
||||||
inputBuffer.clear();
|
inputBuffer.clear();
|
||||||
availableInputBuffers.add(inputBuffer);
|
availableInputBuffers.add(inputBuffer);
|
||||||
}
|
}
|
||||||
|
|
@ -138,6 +141,7 @@ import java.util.PriorityQueue;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
|
queuedInputBufferCount = 0;
|
||||||
playbackPositionUs = 0;
|
playbackPositionUs = 0;
|
||||||
while (!queuedInputBuffers.isEmpty()) {
|
while (!queuedInputBuffers.isEmpty()) {
|
||||||
releaseInputBuffer(queuedInputBuffers.poll());
|
releaseInputBuffer(queuedInputBuffers.poll());
|
||||||
|
|
@ -169,4 +173,32 @@ import java.util.PriorityQueue;
|
||||||
*/
|
*/
|
||||||
protected abstract void decode(SubtitleInputBuffer inputBuffer);
|
protected abstract void decode(SubtitleInputBuffer inputBuffer);
|
||||||
|
|
||||||
|
private static final class CeaInputBuffer extends SubtitleInputBuffer
|
||||||
|
implements Comparable<CeaInputBuffer> {
|
||||||
|
|
||||||
|
private long queuedInputBufferCount;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(@NonNull CeaInputBuffer other) {
|
||||||
|
if (isEndOfStream() != other.isEndOfStream()) {
|
||||||
|
return isEndOfStream() ? 1 : -1;
|
||||||
|
}
|
||||||
|
long delta = timeUs - other.timeUs;
|
||||||
|
if (delta == 0) {
|
||||||
|
delta = queuedInputBufferCount - other.queuedInputBufferCount;
|
||||||
|
if (delta == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return delta > 0 ? 1 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class CeaOutputBuffer extends SubtitleOutputBuffer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void release() {
|
||||||
|
releaseOutputBuffer(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2016 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package com.google.android.exoplayer2.text.cea;
|
|
||||||
|
|
||||||
import com.google.android.exoplayer2.text.SubtitleOutputBuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link SubtitleOutputBuffer} for {@link CeaDecoder}s.
|
|
||||||
*/
|
|
||||||
public final class CeaOutputBuffer extends SubtitleOutputBuffer {
|
|
||||||
|
|
||||||
private final CeaDecoder owner;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param owner The decoder that owns this buffer.
|
|
||||||
*/
|
|
||||||
public CeaOutputBuffer(CeaDecoder owner) {
|
|
||||||
super();
|
|
||||||
this.owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void release() {
|
|
||||||
owner.releaseOutputBuffer(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue