Commit 251c4207 by olly Committed by Oliver Woodman

Experimental parameter for setting a render time limit in MediaCodecRenderer

Currently, MediaCodecRenderer's render loop does not have any time limit. We
always try to drain and feed as much buffers as possible. This may lead to a
pattern of feeding phase takes too much time from previous loop, which makes
the next draining phase drops all buffers, making these buffers available for
feeding all at once, and the pattern keeps repeating.

This CL adds an experimental parameter for setting a time limit. If the time
limit is exceeded, the feeding process stops even if more input could be fed.
The default behavior is unchanged

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=219820386
parent 34797651
......@@ -294,6 +294,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
private Format outputFormat;
private DrmSession<FrameworkMediaCrypto> drmSession;
private DrmSession<FrameworkMediaCrypto> pendingDrmSession;
private long renderTimeLimitMs;
private float rendererOperatingRate;
@Nullable private MediaCodec codec;
@Nullable private Format codecFormat;
......@@ -371,6 +372,21 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecDrainAction = DRAIN_ACTION_NONE;
codecOperatingRate = CODEC_OPERATING_RATE_UNSET;
rendererOperatingRate = 1f;
renderTimeLimitMs = C.TIME_UNSET;
}
/**
* Set a limit on the time a single {@link #render(long, long)} call can spend draining and
* filling the decoder.
*
* <p>This method is experimental, and will be renamed or removed in a future release. It should
* only be called before the renderer is used.
*
* @param renderTimeLimitMs The render time limit in milliseconds, or {@link C#TIME_UNSET} for no
* limit.
*/
public void experimental_setRenderTimeLimitMs(long renderTimeLimitMs) {
this.renderTimeLimitMs = renderTimeLimitMs;
}
@Override
......@@ -623,9 +639,10 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
// We have a format.
maybeInitCodec();
if (codec != null) {
long drainStartTimeMs = SystemClock.elapsedRealtime();
TraceUtil.beginSection("drainAndFeed");
while (drainOutputBuffer(positionUs, elapsedRealtimeUs)) {}
while (feedInputBuffer()) {}
while (feedInputBuffer() && shouldContinueFeeding(drainStartTimeMs)) {}
TraceUtil.endSection();
} else {
decoderCounters.skippedInputBufferCount += skipSource(positionUs);
......@@ -852,6 +869,11 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
onCodecInitialized(codecName, codecInitializedTimestamp, elapsed);
}
private boolean shouldContinueFeeding(long drainStartTimeMs) {
return renderTimeLimitMs == C.TIME_UNSET
|| SystemClock.elapsedRealtime() - drainStartTimeMs < renderTimeLimitMs;
}
private void getCodecBuffers(MediaCodec codec) {
if (Util.SDK_INT < 21) {
inputBuffers = codec.getInputBuffers();
......
......@@ -170,6 +170,8 @@ public final class DefaultBandwidthMeter implements BandwidthMeter, TransferList
/**
* Sets whether to reset if the network type changes.
*
* <p>This method is experimental, and will be renamed or removed in a future release.
*
* @param resetOnNetworkTypeChange Whether to reset if the network type changes.
* @return This builder.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment