Fail on HLS+TS loss of sync

Issue:#3632

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182202289
This commit is contained in:
aquilescanta 2018-01-17 05:59:50 -08:00 committed by Oliver Woodman
parent 0708aa87ba
commit 0697fb3955
3 changed files with 19 additions and 7 deletions

View File

@ -41,13 +41,15 @@
* Support in-band Emsg events targeting player with scheme id * Support in-band Emsg events targeting player with scheme id
"urn:mpeg:dash:event:2012" and scheme value of either "1", "2" or "3". "urn:mpeg:dash:event:2012" and scheme value of either "1", "2" or "3".
* Support DASH manifest EventStream elements. * Support DASH manifest EventStream elements.
* HLS: Add opt-in support for chunkless preparation in HLS. This allows an
HLS source to finish preparation without downloading any chunks, which can
significantly reduce initial buffering time
([#3149](https://github.com/google/ExoPlayer/issues/3149)).
* DefaultTrackSelector: * DefaultTrackSelector:
* Replace `DefaultTrackSelector.Parameters` copy methods with a builder. * Replace `DefaultTrackSelector.Parameters` copy methods with a builder.
* Support disabling of individual text track selection flags. * Support disabling of individual text track selection flags.
* HLS:
* Add opt-in support for chunkless preparation in HLS. This allows an
HLS source to finish preparation without downloading any chunks, which can
significantly reduce initial buffering time
([#3149](https://github.com/google/ExoPlayer/issues/3149)).
* Fail on loss of sync with Transport Stream.
* New Cast extension: Simplifies toggling between local and Cast playbacks. * New Cast extension: Simplifies toggling between local and Cast playbacks.
* Audio: Support TrueHD passthrough for rechunked samples in Matroska files * Audio: Support TrueHD passthrough for rechunked samples in Matroska files
([#2147](https://github.com/google/ExoPlayer/issues/2147)). ([#2147](https://github.com/google/ExoPlayer/issues/2147)).

View File

@ -20,6 +20,7 @@ import android.util.SparseArray;
import android.util.SparseBooleanArray; import android.util.SparseBooleanArray;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.ExtractorInput; import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.extractor.ExtractorOutput; import com.google.android.exoplayer2.extractor.ExtractorOutput;
@ -122,6 +123,7 @@ public final class TsExtractor implements Extractor {
private int remainingPmts; private int remainingPmts;
private boolean tracksEnded; private boolean tracksEnded;
private TsPayloadReader id3Reader; private TsPayloadReader id3Reader;
private int bytesSinceLastSync;
public TsExtractor() { public TsExtractor() {
this(0); this(0);
@ -163,7 +165,7 @@ public final class TsExtractor implements Extractor {
timestampAdjusters = new ArrayList<>(); timestampAdjusters = new ArrayList<>();
timestampAdjusters.add(timestampAdjuster); timestampAdjusters.add(timestampAdjuster);
} }
tsPacketBuffer = new ParsableByteArray(BUFFER_SIZE); tsPacketBuffer = new ParsableByteArray(new byte[BUFFER_SIZE], 0);
trackIds = new SparseBooleanArray(); trackIds = new SparseBooleanArray();
tsPayloadReaders = new SparseArray<>(); tsPayloadReaders = new SparseArray<>();
continuityCounters = new SparseIntArray(); continuityCounters = new SparseIntArray();
@ -206,6 +208,7 @@ public final class TsExtractor implements Extractor {
continuityCounters.clear(); continuityCounters.clear();
// Elementary stream readers' state should be cleared to get consistent behaviours when seeking. // Elementary stream readers' state should be cleared to get consistent behaviours when seeking.
resetPayloadReaders(); resetPayloadReaders();
bytesSinceLastSync = 0;
} }
@Override @Override
@ -238,8 +241,9 @@ public final class TsExtractor implements Extractor {
} }
// Note: See ISO/IEC 13818-1, section 2.4.3.2 for details of the header format. // Note: See ISO/IEC 13818-1, section 2.4.3.2 for details of the header format.
final int limit = tsPacketBuffer.limit(); int limit = tsPacketBuffer.limit();
int position = tsPacketBuffer.getPosition(); int position = tsPacketBuffer.getPosition();
int searchStart = position;
while (position < limit && data[position] != TS_SYNC_BYTE) { while (position < limit && data[position] != TS_SYNC_BYTE) {
position++; position++;
} }
@ -247,8 +251,13 @@ public final class TsExtractor implements Extractor {
int endOfPacket = position + TS_PACKET_SIZE; int endOfPacket = position + TS_PACKET_SIZE;
if (endOfPacket > limit) { if (endOfPacket > limit) {
bytesSinceLastSync += position - searchStart;
if (mode == MODE_HLS && bytesSinceLastSync > TS_PACKET_SIZE * 2) {
throw new ParserException("Cannot find sync byte. Most likely not a Transport Stream.");
}
return RESULT_CONTINUE; return RESULT_CONTINUE;
} }
bytesSinceLastSync = 0;
int tsPacketHeader = tsPacketBuffer.readInt(); int tsPacketHeader = tsPacketBuffer.readInt();
if ((tsPacketHeader & 0x800000) != 0) { // transport_error_indicator if ((tsPacketHeader & 0x800000) != 0) { // transport_error_indicator

View File

@ -20,6 +20,7 @@ import android.util.Log;
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.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.extractor.DummyTrackOutput; import com.google.android.exoplayer2.extractor.DummyTrackOutput;
import com.google.android.exoplayer2.extractor.ExtractorOutput; import com.google.android.exoplayer2.extractor.ExtractorOutput;
@ -610,7 +611,7 @@ import java.util.Arrays;
} }
return Loader.DONT_RETRY; return Loader.DONT_RETRY;
} else { } else {
return Loader.RETRY; return error instanceof ParserException ? Loader.DONT_RETRY_FATAL : Loader.RETRY;
} }
} }