mirror of
https://github.com/Genymobile/scrcpy.git
synced 2026-04-21 01:33:36 +00:00
Convert screen encoder to async processor
Contrary to the other tasks (controller and audio capture/encoding), the screen encoder was executed synchronously. As a consequence, scrcpy-server could not terminate until the screen encoder returned. Convert it to an async processor. This allows to terminate on controller error, and this paves the way to disable video mirroring. PR #3978 <https://github.com/Genymobile/scrcpy/pull/3978>
This commit is contained in:
parent
751a3653a0
commit
feab87053a
6 changed files with 105 additions and 20 deletions
|
|
@ -9,6 +9,35 @@ import java.util.List;
|
|||
|
||||
public final class Server {
|
||||
|
||||
private static class Completion {
|
||||
private int running;
|
||||
private boolean fatalError;
|
||||
|
||||
Completion(int running) {
|
||||
this.running = running;
|
||||
}
|
||||
|
||||
synchronized void addCompleted(boolean fatalError) {
|
||||
--running;
|
||||
if (fatalError) {
|
||||
this.fatalError = true;
|
||||
}
|
||||
if (running == 0 || this.fatalError) {
|
||||
notify();
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void await() {
|
||||
try {
|
||||
while (running > 0 && !fatalError) {
|
||||
wait();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Server() {
|
||||
// not instantiable
|
||||
}
|
||||
|
|
@ -122,22 +151,17 @@ public final class Server {
|
|||
options.getSendFrameMeta());
|
||||
ScreenEncoder screenEncoder = new ScreenEncoder(device, videoStreamer, options.getVideoBitRate(), options.getMaxFps(),
|
||||
options.getVideoCodecOptions(), options.getVideoEncoder(), options.getDownsizeOnError());
|
||||
asyncProcessors.add(screenEncoder);
|
||||
|
||||
Completion completion = new Completion(asyncProcessors.size());
|
||||
for (AsyncProcessor asyncProcessor : asyncProcessors) {
|
||||
asyncProcessor.start();
|
||||
asyncProcessor.start((fatalError) -> {
|
||||
completion.addCompleted(fatalError);
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
// synchronous
|
||||
screenEncoder.streamScreen();
|
||||
} catch (IOException e) {
|
||||
// Broken pipe is expected on close, because the socket is closed by the client
|
||||
if (!IO.isBrokenPipe(e)) {
|
||||
Ln.e("Video encoding error", e);
|
||||
}
|
||||
}
|
||||
completion.await();
|
||||
} finally {
|
||||
Ln.d("Screen streaming stopped");
|
||||
initThread.interrupt();
|
||||
for (AsyncProcessor asyncProcessor : asyncProcessors) {
|
||||
asyncProcessor.stop();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue