mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-26 14:32:42 +00:00
Use a separate HandlerThread for Choreographer callbacks
This commit is contained in:
parent
0c065dcc1f
commit
5b456aba27
@ -23,7 +23,8 @@ import android.media.MediaCodec.BufferInfo;
|
|||||||
import android.media.MediaCodec.CodecException;
|
import android.media.MediaCodec.CodecException;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.HandlerThread;
|
||||||
|
import android.os.Process;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.util.Range;
|
import android.util.Range;
|
||||||
import android.view.Choreographer;
|
import android.view.Choreographer;
|
||||||
@ -88,6 +89,8 @@ 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 long lastRenderedFrameTimeNanos;
|
||||||
|
private HandlerThread choreographerHandlerThread;
|
||||||
|
private Handler choreographerHandler;
|
||||||
|
|
||||||
private int numSpsIn;
|
private int numSpsIn;
|
||||||
private int numPpsIn;
|
private int numPpsIn;
|
||||||
@ -478,6 +481,26 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
|
|||||||
Choreographer.getInstance().postFrameCallback(this);
|
Choreographer.getInstance().postFrameCallback(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startChoreographerThread() {
|
||||||
|
if (prefs.framePacing != PreferenceConfiguration.FRAME_PACING_BALANCED) {
|
||||||
|
// Not using Choreographer in this pacing mode
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We use a separate thread to avoid any main thread delays from delaying rendering
|
||||||
|
choreographerHandlerThread = new HandlerThread("Video - Choreographer", Process.THREAD_PRIORITY_DEFAULT + Process.THREAD_PRIORITY_MORE_FAVORABLE);
|
||||||
|
choreographerHandlerThread.start();
|
||||||
|
|
||||||
|
// Start the frame callbacks
|
||||||
|
choreographerHandler = new Handler(choreographerHandlerThread.getLooper());
|
||||||
|
choreographerHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Choreographer.getInstance().postFrameCallback(MediaCodecDecoderRenderer.this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void startRendererThread()
|
private void startRendererThread()
|
||||||
{
|
{
|
||||||
rendererThread = new Thread() {
|
rendererThread = new Thread() {
|
||||||
@ -620,18 +643,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
|
|||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
startRendererThread();
|
startRendererThread();
|
||||||
|
startChoreographerThread();
|
||||||
// Start Choreographer callbacks for rendering with frame pacing in balanced mode
|
|
||||||
// NB: This must be done on a thread with a looper!
|
|
||||||
if (prefs.framePacing == PreferenceConfiguration.FRAME_PACING_BALANCED) {
|
|
||||||
Handler h = new Handler(Looper.getMainLooper());
|
|
||||||
h.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Choreographer.getInstance().postFrameCallback(MediaCodecDecoderRenderer.this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// !!! May be called even if setup()/start() fails !!!
|
// !!! May be called even if setup()/start() fails !!!
|
||||||
@ -644,12 +656,15 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
|
|||||||
rendererThread.interrupt();
|
rendererThread.interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Halt further Choreographer callbacks
|
// Post a quit message to the Choreographer looper (if we have one)
|
||||||
if (prefs.framePacing == PreferenceConfiguration.FRAME_PACING_BALANCED) {
|
if (choreographerHandler != null) {
|
||||||
Handler h = new Handler(Looper.getMainLooper());
|
choreographerHandler.post(new Runnable() {
|
||||||
h.post(new Runnable() {
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
// Don't allow any further messages to be queued
|
||||||
|
choreographerHandlerThread.quit();
|
||||||
|
|
||||||
|
// Deregister the frame callback (if registered)
|
||||||
Choreographer.getInstance().removeFrameCallback(MediaCodecDecoderRenderer.this);
|
Choreographer.getInstance().removeFrameCallback(MediaCodecDecoderRenderer.this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -661,6 +676,20 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
|
|||||||
// May be called already, but we'll call it now to be safe
|
// May be called already, but we'll call it now to be safe
|
||||||
prepareForStop();
|
prepareForStop();
|
||||||
|
|
||||||
|
// Wait for the Choreographer looper to shut down (if we have one)
|
||||||
|
if (choreographerHandlerThread != null) {
|
||||||
|
try {
|
||||||
|
choreographerHandlerThread.join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
|
||||||
|
// InterruptedException clears the thread's interrupt status. Since we can't
|
||||||
|
// handle that here, we will re-interrupt the thread to set the interrupt
|
||||||
|
// status back to true.
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for the renderer thread to shut down
|
// Wait for the renderer thread to shut down
|
||||||
try {
|
try {
|
||||||
rendererThread.join();
|
rendererThread.join();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user