mirror of
https://github.com/samsonjs/media.git
synced 2026-03-26 09:35:47 +00:00
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:
parent
68156ac7a4
commit
0909446133
9 changed files with 85 additions and 28 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -253,6 +253,11 @@ public final class SingleSampleMediaSource implements MediaPeriod, MediaSource,
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skipToKeyframeBefore(long timeUs) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
// Loader.Callback implementation.
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue