Don't let renderer input buffer get too big if codec not available.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=128082468
This commit is contained in:
eguven 2016-07-21 11:14:43 -07:00 committed by Oliver Woodman
parent 68156ac7a4
commit 0909446133
9 changed files with 85 additions and 28 deletions

View file

@ -157,25 +157,29 @@ public final class LibvpxVideoRenderer extends BaseRenderer {
return;
}
try {
if (decoder == null) {
// If we don't have a decoder yet, we need to instantiate one.
long codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createVpxDecoder");
decoder = new VpxDecoder(NUM_BUFFERS, NUM_BUFFERS, INITIAL_INPUT_BUFFER_SIZE);
decoder.setOutputMode(outputMode);
if (isRendererAvailable()) {
try {
if (decoder == null) {
// If we don't have a decoder yet, we need to instantiate one.
long codecInitializingTimestamp = SystemClock.elapsedRealtime();
TraceUtil.beginSection("createVpxDecoder");
decoder = new VpxDecoder(NUM_BUFFERS, NUM_BUFFERS, INITIAL_INPUT_BUFFER_SIZE);
decoder.setOutputMode(outputMode);
TraceUtil.endSection();
long codecInitializedTimestamp = SystemClock.elapsedRealtime();
eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp,
codecInitializedTimestamp - codecInitializingTimestamp);
decoderCounters.codecInitCount++;
}
TraceUtil.beginSection("drainAndFeed");
while (drainOutputBuffer(positionUs)) {}
while (feedInputBuffer()) {}
TraceUtil.endSection();
long codecInitializedTimestamp = SystemClock.elapsedRealtime();
eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp,
codecInitializedTimestamp - codecInitializingTimestamp);
decoderCounters.codecInitCount++;
} catch (VpxDecoderException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
}
TraceUtil.beginSection("drainAndFeed");
while (drainOutputBuffer(positionUs)) {}
while (feedInputBuffer()) {}
TraceUtil.endSection();
} catch (VpxDecoderException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
} else {
skipToKeyframeBefore(positionUs);
}
decoderCounters.ensureUpdated();
}
@ -331,7 +335,8 @@ public final class LibvpxVideoRenderer extends BaseRenderer {
@Override
public boolean isReady() {
if (format != null && (isSourceReady() || outputBuffer != null) && renderedFirstFrame) {
if (format != null && (isSourceReady() || outputBuffer != null)
&& (renderedFirstFrame || !isRendererAvailable())) {
// Ready. If we were joining then we've now joined, so clear the joining deadline.
joiningDeadlineMs = -1;
return true;
@ -385,17 +390,21 @@ public final class LibvpxVideoRenderer extends BaseRenderer {
outputBuffer = null;
format = null;
try {
if (decoder != null) {
decoder.release();
decoder = null;
decoderCounters.codecReleaseCount++;
}
releaseDecoder();
} finally {
decoderCounters.ensureUpdated();
eventDispatcher.disabled(decoderCounters);
}
}
private void releaseDecoder() {
if (decoder != null) {
decoder.release();
decoder = null;
decoderCounters.codecReleaseCount++;
}
}
private boolean readFormat() {
int result = readSource(formatHolder, null);
if (result == C.RESULT_FORMAT_READ) {
@ -428,9 +437,7 @@ public final class LibvpxVideoRenderer extends BaseRenderer {
this.surface = surface;
outputBufferRenderer = null;
outputMode = (surface != null) ? VpxDecoder.OUTPUT_MODE_RGB : VpxDecoder.OUTPUT_MODE_NONE;
if (decoder != null) {
decoder.setOutputMode(outputMode);
}
updateDecoder();
drawnToSurface = false;
}
@ -442,11 +449,23 @@ public final class LibvpxVideoRenderer extends BaseRenderer {
surface = null;
outputMode = (outputBufferRenderer != null) ? VpxDecoder.OUTPUT_MODE_YUV
: VpxDecoder.OUTPUT_MODE_NONE;
updateDecoder();
}
private void updateDecoder() {
if (decoder != null) {
decoder.setOutputMode(outputMode);
if (outputMode == VpxDecoder.OUTPUT_MODE_NONE) {
releaseDecoder();
} else {
decoder.setOutputMode(outputMode);
}
}
}
private boolean isRendererAvailable() {
return surface != null || outputBufferRenderer != null;
}
private void maybeNotifyVideoSizeChanged(final int width, final int height) {
if (previousWidth != width || previousHeight != height) {
previousWidth = width;

View file

@ -263,4 +263,13 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
return readEndOfStream ? streamIsFinal : stream.isReady();
}
/**
* Attempts to skip to the keyframe before the specified time.
*
* @param timeUs The specified time.
*/
protected void skipToKeyframeBefore(long timeUs) {
stream.skipToKeyframeBefore(timeUs);
}
}

View file

@ -477,6 +477,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
while (drainOutputBuffer(positionUs, elapsedRealtimeUs)) {}
while (feedInputBuffer()) {}
TraceUtil.endSection();
} else if (format != null) {
skipToKeyframeBefore(positionUs);
}
decoderCounters.ensureUpdated();
}

View file

@ -610,6 +610,11 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
return ExtractorMediaSource.this.readData(track, formatHolder, buffer);
}
@Override
public void skipToKeyframeBefore(long timeUs) {
sampleQueues[track].skipToKeyframeBefore(timeUs);
}
}
/**

View file

@ -55,4 +55,11 @@ public interface SampleStream {
*/
int readData(FormatHolder formatHolder, DecoderInputBuffer buffer);
/**
* Attempts to skip to the keyframe before the specified time.
*
* @param timeUs The specified time.
*/
void skipToKeyframeBefore(long timeUs);
}

View file

@ -253,6 +253,11 @@ public final class SingleSampleMediaSource implements MediaPeriod, MediaSource,
}
}
@Override
public void skipToKeyframeBefore(long timeUs) {
// do nothing
}
// Loader.Callback implementation.
@Override

View file

@ -192,6 +192,11 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
return sampleQueue.readData(formatHolder, buffer, loadingFinished, lastSeekPositionUs);
}
@Override
public void skipToKeyframeBefore(long timeUs) {
sampleQueue.skipToKeyframeBefore(timeUs);
}
// Loader.Callback implementation.
@Override

View file

@ -619,6 +619,11 @@ import java.util.List;
return HlsSampleStreamWrapper.this.readData(group, formatHolder, buffer);
}
@Override
public void skipToKeyframeBefore(long timeUs) {
sampleQueues.valueAt(group).skipToKeyframeBefore(timeUs);
}
}
}

View file

@ -240,7 +240,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
@Override
public boolean isReady() {
if (renderedFirstFrame && super.isReady()) {
if ((renderedFirstFrame || super.shouldInitCodec()) && super.isReady()) {
// Ready. If we were joining then we've now joined, so clear the joining deadline.
joiningDeadlineMs = -1;
return true;