Extract async processor interface
On the server side, several components are started, stopped and joined. Extract an interface to handle them generically. This will help to support both encoded and raw audio stream, because they will be two different concrete components, but implementing the same interface. PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
This commit is contained in:
parent
65cc9d765d
commit
dc228eaad0
4 changed files with 25 additions and 21 deletions
|
@ -0,0 +1,7 @@
|
||||||
|
package com.genymobile.scrcpy;
|
||||||
|
|
||||||
|
public interface AsyncProcessor {
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
void join() throws InterruptedException;
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ import java.util.List;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
|
||||||
public final class AudioEncoder {
|
public final class AudioEncoder implements AsyncProcessor {
|
||||||
|
|
||||||
private static class InputTask {
|
private static class InputTask {
|
||||||
private final int index;
|
private final int index;
|
||||||
|
|
|
@ -14,7 +14,7 @@ import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class Controller {
|
public class Controller implements AsyncProcessor {
|
||||||
|
|
||||||
private static final int DEFAULT_DEVICE_ID = 0;
|
private static final int DEFAULT_DEVICE_ID = 0;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.os.BatteryManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@ -91,8 +92,7 @@ public final class Server {
|
||||||
Workarounds.fillAppInfo();
|
Workarounds.fillAppInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller controller = null;
|
List<AsyncProcessor> asyncProcessors = new ArrayList<>();
|
||||||
AudioEncoder audioEncoder = null;
|
|
||||||
|
|
||||||
try (DesktopConnection connection = DesktopConnection.open(scid, tunnelForward, audio, control, sendDummyByte)) {
|
try (DesktopConnection connection = DesktopConnection.open(scid, tunnelForward, audio, control, sendDummyByte)) {
|
||||||
if (options.getSendDeviceMeta()) {
|
if (options.getSendDeviceMeta()) {
|
||||||
|
@ -101,24 +101,27 @@ public final class Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (control) {
|
if (control) {
|
||||||
controller = new Controller(device, connection, options.getClipboardAutosync(), options.getPowerOn());
|
Controller controller = new Controller(device, connection, options.getClipboardAutosync(), options.getPowerOn());
|
||||||
controller.start();
|
device.setClipboardListener(text -> controller.getSender().pushClipboardText(text));
|
||||||
|
asyncProcessors.add(controller);
|
||||||
final Controller controllerRef = controller;
|
|
||||||
device.setClipboardListener(text -> controllerRef.getSender().pushClipboardText(text));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audio) {
|
if (audio) {
|
||||||
Streamer audioStreamer = new Streamer(connection.getAudioFd(), options.getAudioCodec(), options.getSendCodecId(),
|
Streamer audioStreamer = new Streamer(connection.getAudioFd(), options.getAudioCodec(), options.getSendCodecId(),
|
||||||
options.getSendFrameMeta());
|
options.getSendFrameMeta());
|
||||||
audioEncoder = new AudioEncoder(audioStreamer, options.getAudioBitRate(), options.getAudioCodecOptions(), options.getAudioEncoder());
|
AudioEncoder audioRecorder = new AudioEncoder(audioStreamer, options.getAudioBitRate(), options.getAudioCodecOptions(), options.getAudioEncoder());
|
||||||
audioEncoder.start();
|
asyncProcessors.add(audioRecorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
Streamer videoStreamer = new Streamer(connection.getVideoFd(), options.getVideoCodec(), options.getSendCodecId(),
|
Streamer videoStreamer = new Streamer(connection.getVideoFd(), options.getVideoCodec(), options.getSendCodecId(),
|
||||||
options.getSendFrameMeta());
|
options.getSendFrameMeta());
|
||||||
ScreenEncoder screenEncoder = new ScreenEncoder(device, videoStreamer, options.getVideoBitRate(), options.getMaxFps(),
|
ScreenEncoder screenEncoder = new ScreenEncoder(device, videoStreamer, options.getVideoBitRate(), options.getMaxFps(),
|
||||||
options.getVideoCodecOptions(), options.getVideoEncoder(), options.getDownsizeOnError());
|
options.getVideoCodecOptions(), options.getVideoEncoder(), options.getDownsizeOnError());
|
||||||
|
|
||||||
|
for (AsyncProcessor asyncProcessor : asyncProcessors) {
|
||||||
|
asyncProcessor.start();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// synchronous
|
// synchronous
|
||||||
screenEncoder.streamScreen();
|
screenEncoder.streamScreen();
|
||||||
|
@ -131,20 +134,14 @@ public final class Server {
|
||||||
} finally {
|
} finally {
|
||||||
Ln.d("Screen streaming stopped");
|
Ln.d("Screen streaming stopped");
|
||||||
initThread.interrupt();
|
initThread.interrupt();
|
||||||
if (audioEncoder != null) {
|
for (AsyncProcessor asyncProcessor : asyncProcessors) {
|
||||||
audioEncoder.stop();
|
asyncProcessor.stop();
|
||||||
}
|
|
||||||
if (controller != null) {
|
|
||||||
controller.stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
initThread.join();
|
initThread.join();
|
||||||
if (audioEncoder != null) {
|
for (AsyncProcessor asyncProcessor : asyncProcessors) {
|
||||||
audioEncoder.join();
|
asyncProcessor.join();
|
||||||
}
|
|
||||||
if (controller != null) {
|
|
||||||
controller.join();
|
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// ignore
|
// ignore
|
||||||
|
|
Loading…
Reference in a new issue