Unconditionally sleep for offload
Unconditionally sleep for offload, if the audio buffer is full. Previously ExoPlayer would not sleep if the expected wake-up was in 2s. This was to prevent underrun if the wake-up was delayed. Experiments have shown that the wakup audio buffer is far more than 2s (around 1min). Additionally, the metric was incorrect because it measured both, AudioTrack + DSP. Finally, this metric was erroneous after a gapless transition, when the head position would reset to 0 and thus the computed delay until next wakeup was too large. PiperOrigin-RevId: 451383701
This commit is contained in:
parent
9649411a4f
commit
01412f4a57
@ -168,15 +168,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
private static final int ACTIVE_INTERVAL_MS = 10;
|
||||
private static final int IDLE_INTERVAL_MS = 1000;
|
||||
/**
|
||||
* Duration under which pausing the main DO_SOME_WORK loop is not expected to yield significant
|
||||
* power saving.
|
||||
*
|
||||
* <p>This value is probably too high, power measurements are needed adjust it, but as renderer
|
||||
* sleep is currently only implemented for audio offload, which uses buffer much bigger than 2s,
|
||||
* this does not matter for now.
|
||||
*/
|
||||
private static final long MIN_RENDERER_SLEEP_DURATION_MS = 2000;
|
||||
/**
|
||||
* Duration for which the player needs to appear stuck before the playback is failed on the
|
||||
* assumption that no further progress will be made. To appear stuck, the player's renderers must
|
||||
@ -2486,11 +2477,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
Renderer.MSG_SET_WAKEUP_LISTENER,
|
||||
new Renderer.WakeupListener() {
|
||||
@Override
|
||||
public void onSleep(long wakeupDeadlineMs) {
|
||||
// Do not sleep if the expected sleep time is not long enough to save significant power.
|
||||
if (wakeupDeadlineMs >= MIN_RENDERER_SLEEP_DURATION_MS) {
|
||||
requestForRendererSleep = true;
|
||||
}
|
||||
public void onSleep() {
|
||||
requestForRendererSleep = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,11 +66,8 @@ public interface Renderer extends PlayerMessage.Target {
|
||||
* The renderer no longer needs to render until the next wakeup.
|
||||
*
|
||||
* <p>Must be called from the thread ExoPlayer invokes the renderer from.
|
||||
*
|
||||
* @param wakeupDeadlineMs Maximum time in milliseconds until {@link #onWakeup()} will be
|
||||
* called.
|
||||
*/
|
||||
void onSleep(long wakeupDeadlineMs);
|
||||
void onSleep();
|
||||
|
||||
/**
|
||||
* The renderer needs to render some frames. The client should call {@link #render(long, long)}
|
||||
|
@ -108,13 +108,8 @@ public interface AudioSink {
|
||||
/** Called when the offload buffer has been partially emptied. */
|
||||
default void onOffloadBufferEmptying() {}
|
||||
|
||||
/**
|
||||
* Called when the offload buffer has been filled completely.
|
||||
*
|
||||
* @param bufferEmptyingDeadlineMs Maximum time in milliseconds until {@link
|
||||
* #onOffloadBufferEmptying()} will be called.
|
||||
*/
|
||||
default void onOffloadBufferFull(long bufferEmptyingDeadlineMs) {}
|
||||
/** Called when the offload buffer has been filled completely. */
|
||||
default void onOffloadBufferFull() {}
|
||||
|
||||
/**
|
||||
* Called when {@link AudioSink} has encountered an error.
|
||||
|
@ -386,11 +386,6 @@ import java.lang.reflect.Method;
|
||||
return bufferSize - bytesPending;
|
||||
}
|
||||
|
||||
/** Returns the duration of audio that is buffered but unplayed. */
|
||||
public long getPendingBufferDurationMs(long writtenFrames) {
|
||||
return Util.usToMs(framesToDurationUs(writtenFrames - getPlaybackHeadPosition()));
|
||||
}
|
||||
|
||||
/** Returns whether the track is in an invalid state and must be recreated. */
|
||||
public boolean isStalled(long writtenFrames) {
|
||||
return forceResetWorkaroundTimeMs != C.TIME_UNSET
|
||||
|
@ -1202,9 +1202,7 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
&& listener != null
|
||||
&& bytesWritten < bytesRemaining
|
||||
&& !isWaitingForOffloadEndOfStreamHandled) {
|
||||
long pendingDurationMs =
|
||||
audioTrackPositionTracker.getPendingBufferDurationMs(writtenEncodedFrames);
|
||||
listener.onOffloadBufferFull(pendingDurationMs);
|
||||
listener.onOffloadBufferFull();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -930,9 +930,9 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOffloadBufferFull(long bufferEmptyingDeadlineMs) {
|
||||
public void onOffloadBufferFull() {
|
||||
if (wakeupListener != null) {
|
||||
wakeupListener.onSleep(bufferEmptyingDeadlineMs);
|
||||
wakeupListener.onSleep();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12154,7 +12154,6 @@ public final class ExoPlayerTest {
|
||||
|
||||
/** {@link FakeRenderer} that can sleep and be woken-up. */
|
||||
private static class FakeSleepRenderer extends FakeRenderer {
|
||||
private static final long WAKEUP_DEADLINE_MS = 60 * C.MICROS_PER_SECOND;
|
||||
private final AtomicBoolean sleepOnNextRender;
|
||||
private final AtomicReference<Renderer.WakeupListener> wakeupListenerReceiver;
|
||||
|
||||
@ -12168,9 +12167,7 @@ public final class ExoPlayerTest {
|
||||
wakeupListenerReceiver.get().onWakeup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call {@link Renderer.WakeupListener#onSleep(long)} on the next {@link #render(long, long)}
|
||||
*/
|
||||
/** Call {@link Renderer.WakeupListener#onSleep()} on the next {@link #render(long, long)} */
|
||||
public FakeSleepRenderer sleepOnNextRender() {
|
||||
sleepOnNextRender.set(true);
|
||||
return this;
|
||||
@ -12190,7 +12187,7 @@ public final class ExoPlayerTest {
|
||||
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
|
||||
super.render(positionUs, elapsedRealtimeUs);
|
||||
if (sleepOnNextRender.compareAndSet(/* expectedValue= */ true, /* newValue= */ false)) {
|
||||
wakeupListenerReceiver.get().onSleep(WAKEUP_DEADLINE_MS);
|
||||
wakeupListenerReceiver.get().onSleep();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user