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:
parent
e90ad9c47d
commit
a56c00268d
@ -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());
|
||||||
|
@ -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);
|
||||||
|
@ -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());
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user