-
-
Notifications
You must be signed in to change notification settings - Fork 11.5k
Discussion on Optimizing Scrcpy Performance #5940
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thank you for your work and your interest. First, a general (meaningful) method is to measure end-to-end latency (for example #646), but to get precise results it requires a high-framerate camera.
It's interesting to see if However, note that the In the past, I also tested to use a local (UNIX) socket on both side (when the computer runs on linux) instead of using a TCP socket on the computer side. But in practice I could not get any measurable improvement, so it was not worth the added complexity to work differently on different platforms.
To get useful results, you should also test real use cases (typically not send a single byte, but full video packets). One possible interesting test would be to get a timestamp when you write to the socket (on the device) and a timestamp when you read from the socket (on the client), and measure the difference for a lot of data, and produce statistics (mean & variance). Of course, the two clocks are different, so you have to convert the timestamps from one side to the clock of the other size, using a simple NTP-like protocol (a single UDP packet round-trip with 2 timestamps from the client and 2 timestamps from the server, cf §The clock synchronization algorithm). Due to clock drift, you must synchronize quite often (every few seconds, depending on the accuracy/precision you want). In practice, depending on many factors, the clock drift might be in the order of ~4 seconds per day (~50ppm).
It's not trivial to compare, especially since with But the code executed in Java or C here is "minimal", the "hard" work is done by the encoder. In both cases there is JNI involved to communicate between C and Java. The most offending part in Java would be to pass buffer data from C to Java to C, but the Therefore, I would expect that writing the code which calls |
Thank you for your reply. Recently, I have been delving deeper into encoding and decoding, such as whether the low-latency flag is also used by the encoder. Regarding the testing methods you mentioned, I will give them a try. I have already run a demo of the clock drift algorithm, and I will continue to update the test results in this issue. As for the copying process you mentioned, I directly passed the socket's file descriptor to C. At this point, using Regarding ADB forward authentication, I didn't quite understand your point. What I meant is that when the device is connected remotely (i.e., when running In this case, if a socket is created on the device with As for testing metrics, I feel that taking the average value over a period of time is a good approach. I use a millisecond-level stopwatch and speed up the camera shutter. However, this can only measure latency roughly and cannot measure the frame rate. It is possible that using the NDK could allow the client to receive more frames, but this is just a guess. I have written a client using the I have also tried SDL2 + FFmpeg to port the complete scrcpy source code to Android, and it runs normally. However, the efficiency is relatively low because it uses software decoding. |
I am currently trying to port Sunshine to the Android platform. In Sunshine, the streaming part is implemented entirely in C/C++, with Java mainly responsible for passing the Surface to C/C++. During the porting process, I began to wonder if the performance of scrcpy could be further optimized by implementing the decoding, streaming, and even event handling in C/C++.
For example, when I use scrcpy to play games, extreme performance and lower latency become more important. Through this issue, I would like to discuss some methods to optimize performance further. We can keep this issue open for a while, and later, I will share an Android-to-Android mirroring application implemented with scrcpy.
I have conducted several tests.
Using Raw IP + Port
This is when connecting to an Android device via wireless adb. I wanted to remove the adb forward process and connect directly via IP + Port. Here is a method to get the file descriptor of a Socket using Java reflection.
I modified DesktopConnection to test this.
I continuously send one byte from the client and the server replies with one byte to calculate the latency. However, during my tests, the latency fluctuated by a few milliseconds, making it difficult to determine if it was truly faster.
Implementing Encoding and Streaming in C/C++
I implemented encoding using NDK at the C/C++ level. Here is all the code I tested with.
JNIBridge.java
Notice the
useNativeEncoder
variable in the code.I have run this test successfully but have not found concrete methods to measure performance accurately. Relying solely on frame rate seems insufficient. Despite sending additional information to calculate performance differences, external factors and latency fluctuations make it challenging to obtain usable results.
Do you have any good ideas for this?
The text was updated successfully, but these errors were encountered: