HLS: Fix slow seeking into long MP3 segments

Issue: #6155
PiperOrigin-RevId: 290117324
This commit is contained in:
olly 2020-01-16 20:11:20 +00:00 committed by Oliver Woodman
parent db75012503
commit 2859a34027
3 changed files with 44 additions and 3 deletions

View file

@ -40,10 +40,11 @@
([#6845](https://github.com/google/ExoPlayer/issues/6845)).
* Support "twos" codec (big endian PCM) in MP4
([#5789](https://github.com/google/ExoPlayer/issues/5789)).
* WAV: Support IMA ADPCM encoded data.
* Show ad group markers in `DefaultTimeBar` even if they are after the end of
the current window
([#6552](https://github.com/google/ExoPlayer/issues/6552)).
* HLS: Fix slow seeking into long MP3 segments
([#6155](https://github.com/google/ExoPlayer/issues/6155)).
* WAV:
* Support IMA ADPCM encoded data.
* Improve support for G.711 A-law and mu-law encoded data.

View file

@ -507,7 +507,23 @@ public class SampleQueue implements TrackOutput {
boolean loadingFinished,
long decodeOnlyUntilUs,
SampleExtrasHolder extrasHolder) {
if (!hasNextSample()) {
// This is a temporary fix for https://github.com/google/ExoPlayer/issues/6155.
// TODO: Remove it and replace it with a fix that discards samples when writing to the queue.
boolean hasNextSample;
int relativeReadIndex = C.INDEX_UNSET;
while ((hasNextSample = hasNextSample())) {
relativeReadIndex = getRelativeIndex(readPosition);
long timeUs = timesUs[relativeReadIndex];
if (timeUs < decodeOnlyUntilUs
&& MimeTypes.allSamplesAreSyncSamples(formats[relativeReadIndex].sampleMimeType)) {
readPosition++;
} else {
break;
}
}
if (!hasNextSample) {
if (loadingFinished || isLastSampleQueued) {
buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
return C.RESULT_BUFFER_READ;
@ -519,7 +535,6 @@ public class SampleQueue implements TrackOutput {
}
}
int relativeReadIndex = getRelativeIndex(readPosition);
if (formatRequired || formats[relativeReadIndex] != downstreamFormat) {
onFormatResult(formats[relativeReadIndex], formatHolder);
return C.RESULT_FORMAT_READ;

View file

@ -142,6 +142,31 @@ public final class MimeTypes {
return BASE_TYPE_APPLICATION.equals(getTopLevelType(mimeType));
}
/**
* Returns true if it is known that all samples in a stream of the given sample MIME type are
* guaranteed to be sync samples (i.e., {@link C#BUFFER_FLAG_KEY_FRAME} is guaranteed to be set on
* every sample).
*
* @param mimeType The sample MIME type.
* @return True if it is known that all samples in a stream of the given sample MIME type are
* guaranteed to be sync samples. False otherwise, including if {@code null} is passed.
*/
public static boolean allSamplesAreSyncSamples(@Nullable String mimeType) {
if (mimeType == null) {
return false;
}
// TODO: Consider adding additional audio MIME types here.
switch (mimeType) {
case AUDIO_AAC:
case AUDIO_MPEG:
case AUDIO_MPEG_L1:
case AUDIO_MPEG_L2:
return true;
default:
return false;
}
}
/**
* Derives a video sample mimeType from a codecs attribute.
*