mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-25 22:13:04 +00:00
Prevent microstutter in balanced mode when streaming at 60 FPS on a 120 Hz display
This commit is contained in:
parent
6f8e719200
commit
226e580a30
@ -86,6 +86,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
|
|||||||
|
|
||||||
private LinkedBlockingQueue<Integer> outputBufferQueue = new LinkedBlockingQueue<>();
|
private LinkedBlockingQueue<Integer> outputBufferQueue = new LinkedBlockingQueue<>();
|
||||||
private static final int OUTPUT_BUFFER_QUEUE_LIMIT = 2;
|
private static final int OUTPUT_BUFFER_QUEUE_LIMIT = 2;
|
||||||
|
private long lastRenderedFrameTimeNanos;
|
||||||
|
|
||||||
private int numSpsIn;
|
private int numSpsIn;
|
||||||
private int numPpsIn;
|
private int numPpsIn;
|
||||||
@ -419,21 +420,28 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render up to one frame when in frame pacing mode.
|
// Don't render unless a new frame is due. This prevents microstutter when streaming
|
||||||
//
|
// at a frame rate that doesn't match the display (such as 60 FPS on 120 Hz).
|
||||||
// NB: Since the queue limit is 2, we won't starve the decoder of output buffers
|
long actualFrameTimeDeltaNs = frameTimeNanos - lastRenderedFrameTimeNanos;
|
||||||
// by holding onto them for too long. This also ensures we will have that 1 extra
|
long expectedFrameTimeDeltaNs = 800000000 / refreshRate; // within 80% of the next frame
|
||||||
// frame of buffer to smooth over network/rendering jitter.
|
if (actualFrameTimeDeltaNs >= expectedFrameTimeDeltaNs) {
|
||||||
Integer nextOutputBuffer = outputBufferQueue.poll();
|
// Render up to one frame when in frame pacing mode.
|
||||||
if (nextOutputBuffer != null) {
|
//
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
// NB: Since the queue limit is 2, we won't starve the decoder of output buffers
|
||||||
videoDecoder.releaseOutputBuffer(nextOutputBuffer, frameTimeNanos);
|
// by holding onto them for too long. This also ensures we will have that 1 extra
|
||||||
}
|
// frame of buffer to smooth over network/rendering jitter.
|
||||||
else {
|
Integer nextOutputBuffer = outputBufferQueue.poll();
|
||||||
videoDecoder.releaseOutputBuffer(nextOutputBuffer, true);
|
if (nextOutputBuffer != null) {
|
||||||
}
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
videoDecoder.releaseOutputBuffer(nextOutputBuffer, frameTimeNanos);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
videoDecoder.releaseOutputBuffer(nextOutputBuffer, true);
|
||||||
|
}
|
||||||
|
|
||||||
activeWindowVideoStats.totalFramesRendered++;
|
lastRenderedFrameTimeNanos = frameTimeNanos;
|
||||||
|
activeWindowVideoStats.totalFramesRendered++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request another callback for next frame
|
// Request another callback for next frame
|
||||||
|
Loading…
x
Reference in New Issue
Block a user