Remove ability to disable frame accurate seek.

Everything I've seen that uses ExoPlayer sets it to true, and
setting it to false is poorly supported / likely to result in
bad initial A/V sync after each seek.
This commit is contained in:
Oliver Woodman 2015-07-30 10:05:04 +01:00
parent e90ad9c47d
commit a56c00268d
7 changed files with 28 additions and 34 deletions

View File

@ -274,7 +274,7 @@ public class DashRendererBuilder implements RendererBuilder {
new AdaptiveEvaluator(bandwidthMeter), LIVE_EDGE_LATENCY_MS, elapsedRealtimeOffset, new AdaptiveEvaluator(bandwidthMeter), LIVE_EDGE_LATENCY_MS, elapsedRealtimeOffset,
mainHandler, player); mainHandler, player);
ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl, ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl,
VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, mainHandler, player, VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player,
DemoPlayer.TYPE_VIDEO); DemoPlayer.TYPE_VIDEO);
videoRenderer = new MediaCodecVideoTrackRenderer(videoSampleSource, drmSessionManager, true, videoRenderer = new MediaCodecVideoTrackRenderer(videoSampleSource, drmSessionManager, true,
MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, null, mainHandler, player, 50); MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, null, mainHandler, player, 50);
@ -332,7 +332,7 @@ public class DashRendererBuilder implements RendererBuilder {
audioTrackNameList.toArray(audioTrackNames); audioTrackNameList.toArray(audioTrackNames);
audioChunkSource = new MultiTrackChunkSource(audioChunkSourceList); audioChunkSource = new MultiTrackChunkSource(audioChunkSourceList);
SampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl, SampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl,
AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, mainHandler, player, AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player,
DemoPlayer.TYPE_AUDIO); DemoPlayer.TYPE_AUDIO);
audioRenderer = new MediaCodecAudioTrackRenderer(audioSampleSource, drmSessionManager, true, audioRenderer = new MediaCodecAudioTrackRenderer(audioSampleSource, drmSessionManager, true,
mainHandler, player); mainHandler, player);
@ -370,7 +370,7 @@ public class DashRendererBuilder implements RendererBuilder {
textTrackNameList.toArray(textTrackNames); textTrackNameList.toArray(textTrackNames);
textChunkSource = new MultiTrackChunkSource(textChunkSourceList); textChunkSource = new MultiTrackChunkSource(textChunkSourceList);
SampleSource textSampleSource = new ChunkSampleSource(textChunkSource, loadControl, SampleSource textSampleSource = new ChunkSampleSource(textChunkSource, loadControl,
TEXT_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, mainHandler, player, TEXT_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player,
DemoPlayer.TYPE_TEXT); DemoPlayer.TYPE_TEXT);
textRenderer = new TextTrackRenderer(textSampleSource, player, mainHandler.getLooper(), textRenderer = new TextTrackRenderer(textSampleSource, player, mainHandler.getLooper(),
new TtmlParser(), new WebvttParser()); new TtmlParser(), new WebvttParser());

View File

@ -150,7 +150,7 @@ public class HlsRendererBuilder implements RendererBuilder {
HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter, HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter,
variantIndices, HlsChunkSource.ADAPTIVE_MODE_SPLICE, audioCapabilities); variantIndices, HlsChunkSource.ADAPTIVE_MODE_SPLICE, audioCapabilities);
HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl, HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl,
BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, mainHandler, player, DemoPlayer.TYPE_VIDEO); BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player, DemoPlayer.TYPE_VIDEO);
MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource, MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource,
MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50); MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50);
MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource); MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);

View File

@ -196,7 +196,7 @@ public class SmoothStreamingRendererBuilder implements RendererBuilder {
videoStreamElementIndex, videoTrackIndices, videoDataSource, videoStreamElementIndex, videoTrackIndices, videoDataSource,
new AdaptiveEvaluator(bandwidthMeter), LIVE_EDGE_LATENCY_MS); new AdaptiveEvaluator(bandwidthMeter), LIVE_EDGE_LATENCY_MS);
ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl, ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl,
VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, mainHandler, player, VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player,
DemoPlayer.TYPE_VIDEO); DemoPlayer.TYPE_VIDEO);
videoRenderer = new MediaCodecVideoTrackRenderer(videoSampleSource, drmSessionManager, true, videoRenderer = new MediaCodecVideoTrackRenderer(videoSampleSource, drmSessionManager, true,
MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, null, mainHandler, player, 50); MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, null, mainHandler, player, 50);
@ -227,7 +227,7 @@ public class SmoothStreamingRendererBuilder implements RendererBuilder {
} }
audioChunkSource = new MultiTrackChunkSource(audioChunkSources); audioChunkSource = new MultiTrackChunkSource(audioChunkSources);
ChunkSampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl, ChunkSampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl,
AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, mainHandler, player, AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player,
DemoPlayer.TYPE_AUDIO); DemoPlayer.TYPE_AUDIO);
audioRenderer = new MediaCodecAudioTrackRenderer(audioSampleSource, drmSessionManager, true, audioRenderer = new MediaCodecAudioTrackRenderer(audioSampleSource, drmSessionManager, true,
mainHandler, player); mainHandler, player);
@ -258,7 +258,7 @@ public class SmoothStreamingRendererBuilder implements RendererBuilder {
} }
textChunkSource = new MultiTrackChunkSource(textChunkSources); textChunkSource = new MultiTrackChunkSource(textChunkSources);
ChunkSampleSource ttmlSampleSource = new ChunkSampleSource(textChunkSource, loadControl, ChunkSampleSource ttmlSampleSource = new ChunkSampleSource(textChunkSource, loadControl,
TEXT_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, mainHandler, player, TEXT_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player,
DemoPlayer.TYPE_TEXT); DemoPlayer.TYPE_TEXT);
textRenderer = new TextTrackRenderer(ttmlSampleSource, player, mainHandler.getLooper(), textRenderer = new TextTrackRenderer(ttmlSampleSource, player, mainHandler.getLooper(),
new TtmlParser()); new TtmlParser());

View File

@ -114,7 +114,7 @@ public class DashRendererBuilder implements ManifestCallback<MediaPresentationDe
throw new IllegalStateException("Unexpected mime type: " + mimeType); throw new IllegalStateException("Unexpected mime type: " + mimeType);
} }
ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl, ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl,
VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true); VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE);
videoRenderer = new LibvpxVideoTrackRenderer(videoSampleSource, videoRenderer = new LibvpxVideoTrackRenderer(videoSampleSource,
true, player.getMainHandler(), player, 50); true, player.getMainHandler(), player, 50);
} }
@ -133,7 +133,7 @@ public class DashRendererBuilder implements ManifestCallback<MediaPresentationDe
} }
audioChunkSource = new MultiTrackChunkSource(audioChunkSources); audioChunkSource = new MultiTrackChunkSource(audioChunkSources);
SampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl, SampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl,
AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true); AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE);
if (manifestUrl.contains("opus")) { // TODO: Need a better logic here. if (manifestUrl.contains("opus")) { // TODO: Need a better logic here.
audioRenderer = new LibopusAudioTrackRenderer(audioSampleSource); audioRenderer = new LibopusAudioTrackRenderer(audioSampleSource);
} else { } else {

View File

@ -68,7 +68,6 @@ public class ChunkSampleSource implements SampleSource, SampleSourceReader, Load
private final List<BaseMediaChunk> readOnlyMediaChunks; private final List<BaseMediaChunk> readOnlyMediaChunks;
private final DefaultTrackOutput sampleQueue; private final DefaultTrackOutput sampleQueue;
private final int bufferSizeContribution; private final int bufferSizeContribution;
private final boolean frameAccurateSeeking;
private final Handler eventHandler; private final Handler eventHandler;
private final EventListener eventListener; private final EventListener eventListener;
private final int minLoadableRetryCount; private final int minLoadableRetryCount;
@ -91,24 +90,23 @@ public class ChunkSampleSource implements SampleSource, SampleSourceReader, Load
private Format downstreamFormat; private Format downstreamFormat;
public ChunkSampleSource(ChunkSource chunkSource, LoadControl loadControl, public ChunkSampleSource(ChunkSource chunkSource, LoadControl loadControl,
int bufferSizeContribution, boolean frameAccurateSeeking) { int bufferSizeContribution) {
this(chunkSource, loadControl, bufferSizeContribution, frameAccurateSeeking, null, null, 0); this(chunkSource, loadControl, bufferSizeContribution, null, null, 0);
} }
public ChunkSampleSource(ChunkSource chunkSource, LoadControl loadControl, public ChunkSampleSource(ChunkSource chunkSource, LoadControl loadControl,
int bufferSizeContribution, boolean frameAccurateSeeking, Handler eventHandler, int bufferSizeContribution, Handler eventHandler, EventListener eventListener,
EventListener eventListener, int eventSourceId) { int eventSourceId) {
this(chunkSource, loadControl, bufferSizeContribution, frameAccurateSeeking, eventHandler, this(chunkSource, loadControl, bufferSizeContribution, eventHandler, eventListener,
eventListener, eventSourceId, DEFAULT_MIN_LOADABLE_RETRY_COUNT); eventSourceId, DEFAULT_MIN_LOADABLE_RETRY_COUNT);
} }
public ChunkSampleSource(ChunkSource chunkSource, LoadControl loadControl, public ChunkSampleSource(ChunkSource chunkSource, LoadControl loadControl,
int bufferSizeContribution, boolean frameAccurateSeeking, Handler eventHandler, int bufferSizeContribution, Handler eventHandler, EventListener eventListener,
EventListener eventListener, int eventSourceId, int minLoadableRetryCount) { int eventSourceId, int minLoadableRetryCount) {
this.chunkSource = chunkSource; this.chunkSource = chunkSource;
this.loadControl = loadControl; this.loadControl = loadControl;
this.bufferSizeContribution = bufferSizeContribution; this.bufferSizeContribution = bufferSizeContribution;
this.frameAccurateSeeking = frameAccurateSeeking;
this.eventHandler = eventHandler; this.eventHandler = eventHandler;
this.eventListener = eventListener; this.eventListener = eventListener;
this.eventSourceId = eventSourceId; this.eventSourceId = eventSourceId;
@ -250,7 +248,7 @@ public class ChunkSampleSource implements SampleSource, SampleSourceReader, Load
} }
if (sampleQueue.getSample(sampleHolder)) { if (sampleQueue.getSample(sampleHolder)) {
boolean decodeOnly = frameAccurateSeeking && sampleHolder.timeUs < lastSeekPositionUs; boolean decodeOnly = sampleHolder.timeUs < lastSeekPositionUs;
sampleHolder.flags |= decodeOnly ? C.SAMPLE_FLAG_DECODE_ONLY : 0; sampleHolder.flags |= decodeOnly ? C.SAMPLE_FLAG_DECODE_ONLY : 0;
onSampleRead(currentChunk, sampleHolder); onSampleRead(currentChunk, sampleHolder);
return SAMPLE_READ; return SAMPLE_READ;

View File

@ -154,7 +154,6 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader,
private final int requestedBufferSize; private final int requestedBufferSize;
private final SparseArray<InternalTrackOutput> sampleQueues; private final SparseArray<InternalTrackOutput> sampleQueues;
private final int minLoadableRetryCount; private final int minLoadableRetryCount;
private final boolean frameAccurateSeeking;
private final Uri uri; private final Uri uri;
private final DataSource dataSource; private final DataSource dataSource;
@ -269,7 +268,6 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader,
extractorHolder = new ExtractorHolder(extractors, this); extractorHolder = new ExtractorHolder(extractors, this);
sampleQueues = new SparseArray<>(); sampleQueues = new SparseArray<>();
pendingResetPositionUs = NO_RESET_PENDING; pendingResetPositionUs = NO_RESET_PENDING;
frameAccurateSeeking = true;
} }
@Override @Override
@ -390,7 +388,7 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader,
} }
if (sampleQueue.getSample(sampleHolder)) { if (sampleQueue.getSample(sampleHolder)) {
boolean decodeOnly = frameAccurateSeeking && sampleHolder.timeUs < lastSeekPositionUs; boolean decodeOnly = sampleHolder.timeUs < lastSeekPositionUs;
sampleHolder.flags |= decodeOnly ? C.SAMPLE_FLAG_DECODE_ONLY : 0; sampleHolder.flags |= decodeOnly ? C.SAMPLE_FLAG_DECODE_ONLY : 0;
if (havePendingNextSampleUs) { if (havePendingNextSampleUs) {
// Set the offset to make the timestamp of this sample equal to pendingNextSampleUs. // Set the offset to make the timestamp of this sample equal to pendingNextSampleUs.

View File

@ -56,7 +56,6 @@ public class HlsSampleSource implements SampleSource, SampleSourceReader, Loader
private final HlsChunkSource chunkSource; private final HlsChunkSource chunkSource;
private final LinkedList<HlsExtractorWrapper> extractors; private final LinkedList<HlsExtractorWrapper> extractors;
private final boolean frameAccurateSeeking;
private final int minLoadableRetryCount; private final int minLoadableRetryCount;
private final int bufferSizeContribution; private final int bufferSizeContribution;
@ -92,24 +91,23 @@ public class HlsSampleSource implements SampleSource, SampleSourceReader, Loader
private long currentLoadStartTimeMs; private long currentLoadStartTimeMs;
public HlsSampleSource(HlsChunkSource chunkSource, LoadControl loadControl, public HlsSampleSource(HlsChunkSource chunkSource, LoadControl loadControl,
int bufferSizeContribution, boolean frameAccurateSeeking) { int bufferSizeContribution) {
this(chunkSource, loadControl, bufferSizeContribution, frameAccurateSeeking, null, null, 0); this(chunkSource, loadControl, bufferSizeContribution, null, null, 0);
} }
public HlsSampleSource(HlsChunkSource chunkSource, LoadControl loadControl, public HlsSampleSource(HlsChunkSource chunkSource, LoadControl loadControl,
int bufferSizeContribution, boolean frameAccurateSeeking, Handler eventHandler, int bufferSizeContribution, Handler eventHandler, EventListener eventListener,
EventListener eventListener, int eventSourceId) { int eventSourceId) {
this(chunkSource, loadControl, bufferSizeContribution, frameAccurateSeeking, eventHandler, this(chunkSource, loadControl, bufferSizeContribution, eventHandler, eventListener,
eventListener, eventSourceId, DEFAULT_MIN_LOADABLE_RETRY_COUNT); eventSourceId, DEFAULT_MIN_LOADABLE_RETRY_COUNT);
} }
public HlsSampleSource(HlsChunkSource chunkSource, LoadControl loadControl, public HlsSampleSource(HlsChunkSource chunkSource, LoadControl loadControl,
int bufferSizeContribution, boolean frameAccurateSeeking, Handler eventHandler, int bufferSizeContribution, Handler eventHandler, EventListener eventListener,
EventListener eventListener, int eventSourceId, int minLoadableRetryCount) { int eventSourceId, int minLoadableRetryCount) {
this.chunkSource = chunkSource; this.chunkSource = chunkSource;
this.loadControl = loadControl; this.loadControl = loadControl;
this.bufferSizeContribution = bufferSizeContribution; this.bufferSizeContribution = bufferSizeContribution;
this.frameAccurateSeeking = frameAccurateSeeking;
this.minLoadableRetryCount = minLoadableRetryCount; this.minLoadableRetryCount = minLoadableRetryCount;
this.eventHandler = eventHandler; this.eventHandler = eventHandler;
this.eventListener = eventListener; this.eventListener = eventListener;
@ -298,7 +296,7 @@ public class HlsSampleSource implements SampleSource, SampleSourceReader, Loader
} }
if (extractor.getSample(track, sampleHolder)) { if (extractor.getSample(track, sampleHolder)) {
boolean decodeOnly = frameAccurateSeeking && sampleHolder.timeUs < lastSeekPositionUs; boolean decodeOnly = sampleHolder.timeUs < lastSeekPositionUs;
sampleHolder.flags |= decodeOnly ? C.SAMPLE_FLAG_DECODE_ONLY : 0; sampleHolder.flags |= decodeOnly ? C.SAMPLE_FLAG_DECODE_ONLY : 0;
return SAMPLE_READ; return SAMPLE_READ;
} }