当前位置:网站首页>Scrcpy development environment construction and source code reading
Scrcpy development environment construction and source code reading
2022-06-13 06:26:00 【That's right】
This series of blog posts mainly records that I am in scrcpy Documentation during project refactoring , For your reference and memo .
Environmental statement
- 1. operating system ubuntu20-64
- 2. virtual machine VMware 15
- 3. Source code 1.19 edition
git clone https://github.com/Genymobile/scrcpy -b v1.19
cd scrcpy
First step build scrcpy Compile the development environment
1.1 install meson
sudo apt install python3-pip
pip3 install meson
1.2 install ninja
sudo apt install ninja-build
1.3 install java vm
sudo apt install openjdk-11-jdk
export PATH=“ J A V A H O M E / b i n : JAVA_HOME/bin: JAVAHOME/bin:PATH”
1.4 install android sdk
android sdk install , I am through ubuntu20 Install in AndroidStudio-2021 Of IDE Environmental Science ,
And then through adk Management style , download sdk package , The contents are as follows :
[email protected]:~$ ls Android/Sdk/platforms/
android-22 android-24 android-26 android-28 android-30 android-31
[email protected]:~$ ls Android/Sdk/build-tools/
29.0.2 30.0.2 31.0.0
1.5 install Dependency Library
sudo apt install gcc git pkg-config meson ninja-build libsdl2-dev \
libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev
sudo apt install ffmpeg libsdl2-2.0-0 adb
sudo snap install gradle
1.6 Refer to Part 4 for the compilation process
Refer to the description questions , Detailed see :scrcpy Source code in the main directory BUILD.md The document states .
The second step scrcpy Client program walk through
bool scrcpy(const struct scrcpy_options *options) {
static struct scrcpy scrcpy;
struct scrcpy *s = &scrcpy;
server_init(&s->server); ///> 1. server_init()
struct server_params params = {
.serial = options->serial,
.port_range = options->port_range,
.bit_rate = options->bit_rate,
.max_fps = options->max_fps,
.display_id = options->display_id,
.codec_options = options->codec_options,
.encoder_name = options->encoder_name,
.force_adb_forward = options->force_adb_forward,
};
server_start(&s->server, ¶ms); ///> 2. server_start();
server_started = true;
sdl_init_and_configure(options->display, options->render_driver,
options->disable_screensaver);
server_connect_to(&s->server, device_name, &frame_size); ///> 3. server_connect_to();
file_handler_init(&s->file_handler, s->server.serial,
options->push_target); ///> 4. file_handler_init(); socket init & Server code adb push
decoder_init(&s->decoder); ///> 5. decoder_init();
av_log_set_callback(av_log_callback); ///> 6. av_log_set_callback();
static const struct stream_callbacks stream_cbs = {
///> 7. stream_init();
.on_eos = stream_on_eos,
};
stream_init(&s->stream, s->server.video_socket, &stream_cbs, NULL);
stream_add_sink(&s->stream, &dec->packet_sink); ///> 8. stream_add_sink(); dec
stream_add_sink(&s->stream, &rec->packet_sink); ///> 9. stream_add_sink(); rec
controller_init(&s->controller, s->server.control_socket); ///> 10. controller_init(); control_socket
controller_start(&s->controller); ///> 11. controller_start();
struct screen_params screen_params = {
.window_title = window_title,
.frame_size = frame_size,
.always_on_top = options->always_on_top,
.window_x = options->window_x,
.window_y = options->window_y,
.window_width = options->window_width,
.window_height = options->window_height,
.window_borderless = options->window_borderless,
.rotation = options->rotation,
.mipmaps = options->mipmaps,
.fullscreen = options->fullscreen,
.buffering_time = options->display_buffer,
};
screen_init(&s->screen, &screen_params); ///> 12. screen_init();
decoder_add_sink(&s->decoder, &s->screen.frame_sink); ///> 13. decoder_add_sink();
#ifdef HAVE_V4L2
sc_v4l2_sink_init(&s->v4l2_sink, options->v4l2_device, frame_size,
options->v4l2_buffer); ///> 14. sc_v4l2_sink_init();
decoder_add_sink(&s->decoder, &s->v4l2_sink.frame_sink);
#endif
stream_start(&s->stream); ///> 14+. Stream start configuration , Missing the first release , I'm sorry . Add
input_manager_init(&s->input_manager, &s->controller, &s->screen, options); ///> 15. input_manager_init();
ret = event_loop(s, options); ///> 16. event_loop();
///> Program launch releases resource related content
screen_hide_window(&s->screen);
controller_stop(&s->controller);
file_handler_stop(&s->file_handler);
screen_interrupt(&s->screen);
server_stop(&s->server);
stream_join(&s->stream);
sc_v4l2_sink_destroy(&s->v4l2_sink);
screen_join(&s->screen);
screen_destroy(&s->screen);
controller_join(&s->controller);
controller_destroy(&s->controller);
recorder_destroy(&s->recorder);
file_handler_join(&s->file_handler);
file_handler_destroy(&s->file_handler);
server_destroy(&s->server); ///> The destruction server
return ret;
}
- server_init()
struct scrcpy {
///> encapsulation scrcpy Object content
struct server server; //> 1. communication server object
struct screen screen; //> 2. For screen screen object
struct stream stream; //> 3. Video streaming stream object
struct decoder decoder;
struct recorder recorder;
#ifdef HAVE_V4L2
struct sc_v4l2_sink v4l2_sink;
#endif
struct controller controller;
struct file_handler file_handler;
struct input_manager input_manager;
};
- server_start();
bool
server_start(struct server *server, const struct server_params *params) {
push_server(params->serial); ///> 2.1 from client adb push to server
enable_tunnel_any_port(server, params->port_range,
params->force_adb_forward); ///> 2.2 Turn on ADB Port forwarding , go WIFI Pattern , Otherwise, it would be USB ADB Pattern .
server->process = execute_server(server, params); ///> 2.3 Build local ADB client Connect local ADB SERVER .
bool ok = sc_thread_create(&server->wait_server_thread, run_wait_server,
"wait-server", server); ///> 2.4 Local ADB SERVER Establishment and ANDROID ADB DAEMAIN Daemon thread communication .
}
Get the local environment variable , Is there a “SCRCPY_SERVER_PATH” Content , If the environment variable is not set 、 Use the default server-path Content (scrcpy Software startup execution content );
- push_server(params->serial); Function source code reading
///> 2.1. params->serial yes ADB PUSH It's used -s Parameters .
static bool
push_server(const char *serial) {
char *server_path = get_server_path(); /* The software is not installed , Use... In the current path scrcpy-server As the execution path */
if (!server_path) {
return false;
}
/* * * adb push * local_path = /build/server/scrcpy-server Compile the output server program . * remote_path="/data/local/tmp/scrcpy-server.jar" ANDROID Device path and file name . * */
process_t process = adb_push(serial, server_path, DEVICE_SERVER_PATH);
}
///> 2.2 adb_push function
process_t adb_push(const char *serial, const char *local, const char *remote) {
const char *const adb_cmd[] = {
"push", local, remote};
process_t proc = adb_execute(serial, adb_cmd, ARRAY_LEN(adb_cmd));
}
///> 2.3. adb_execute function
process_t adb_execute(const char *serial, const char *const adb_cmd[], size_t len) {
argv[0] = get_adb_command();
argv[1] = "-s";
argv[2] = serial; ///>
memcpy(&argv[i], adb_cmd, len * sizeof(const char *));
enum process_result r = process_execute(argv, &process);
return process;
}
///> 2.4. Establish pipeline 、 Perform system call function : /usr/share/adb push -s serial local_path remote_path
enum process_result process_execute(const char *const argv[], pid_t *pid) {
int fd[2];
pipe(fd);
pid = fork();
fcntl(fd[1], F_SETFD, FD_CLOEXEC);
execvp(argv[0], (char *const *)argv);
write(fd[1], &ret, sizeof(ret));
close(fd[1]);
return ret;
}
- enable_tunnel_any_port()
The software runs to check whether it is enabled ADB FORWORD function , If on, execute enable_tunnel_any_port() function .
enable_tunnel_any_port(server, params->port_range,params->force_adb_forward)
{
for (;;) {
///> Traverse adb port list , Find out which ports you can use .
if (enable_tunnel_forward(server->serial, port)) {
// success
server->local_port = port;
return true;
}
}
}
- server->process = execute_server(server, params)
adopt ADB SHELL function scrcpy-server Procedural methods .
server->process = execute_server(server, params)
{
const char *const cmd[] = {
"shell",
"CLASSPATH=" DEVICE_SERVER_PATH, //> = "/data/local/tmp/scrcpy-server.jar",
"app_process",
#ifdef SERVER_DEBUGGER
# define SERVER_DEBUGGER_PORT "5005"
# ifdef SERVER_DEBUGGER_METHOD_NEW
/* Android 9 and above */
"-XjdwpProvider:internal -XjdwpOptions:transport=dt_socket,suspend=y,"
"server=y,address="
# else
/* Android 8 and below */
"-agentlib:jdwp=transport=dt_socket,suspend=y,server=y,address="
# endif
SERVER_DEBUGGER_PORT,
#endif
"/", // unused
"com.genymobile.scrcpy.Server",
SCRCPY_VERSION,
log_level_to_server_string(params->log_level),
max_size_string,
bit_rate_string,
max_fps_string,
lock_video_orientation_string,
server->tunnel_forward ? "true" : "false",
params->crop ? params->crop : "-",
"true", // always send frame meta (packet boundaries + timestamp)
params->control ? "true" : "false",
display_id_string,
params->show_touches ? "true" : "false",
params->stay_awake ? "true" : "false",
params->codec_options ? params->codec_options : "-",
params->encoder_name ? params->encoder_name : "-",
params->power_off_on_close ? "true" : "false",
};
return adb_execute(server->serial, cmd, ARRAY_LEN(cmd));
}
///> adb_execute() yes ADB Interface API function
adb_execute(server->serial, cmd, ARRAY_LEN(cmd))
{
}
The third step modify scrcpy client adb.c In the code , Observe ADB Execution process content
stay adb.c Of documents 135 Line down , Add the following code
memcpy(&argv[i], adb_cmd, len * sizeof(const char *));
argv[len + i] = NULL;
///> Add the code as follows :
memset(buf,0,sizeof(buf));
for(i=0;i <= (int)len; i++){
memset(cmd,0,sizeof(cmd));
sprintf(cmd,"%s ",argv[i]);
length = strlen(cmd);
memcpy(&buf[base],cmd,length);
base += length;
}
printf("%s, ADB-CMD: %s \n",__FILE__,buf);
///> Add code end
enum process_result r = process_execute(argv, &process);
if (r != PROCESS_SUCCESS) {
show_adb_err_msg(r, argv);
process = PROCESS_NONE;
}
Step four meson Compile source code and verify ANDROID Server program startup logic
[email protected]:~/scrcpy/scrcpy$ export ANDROID_SDK_ROOT=~/Android/Sdk
### (1). meson Compile source code
[email protected]:~/scrcpy/scrcpy$ meson build --buildtype release --strip -Db_lto=true
Directory already configured.
Just run your build command (e.g. ninja) and Meson will regenerate as necessary.
If ninja fails, run "ninja reconfigure" or "meson --reconfigure"
to force Meson to regenerate.
If build failures persist, run "meson setup --wipe" to rebuild from scratch
using the same options as passed when configuring the build.
To change option values, run "meson configure" instead.
### (2). ninja Link compilation results
[email protected]:~/scrcpy/scrcpy$ ninja -C build
ninja: Entering directory `build'
[0/3] Generating scrcpy-server with a custom command
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.3/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 4s
24 actionable tasks: 1 executed, 23 up-to-date
[1/3] Compiling C object app/scrcpy.p/src_adb.c.o
../app/src/adb.c: In function 'adb_execute':
../app/src/adb.c:138:15: warning: comparison of integer expressions of different signedness: 'int' and 'size_t' {
aka 'long unsigned int'} [-Wsign-compare]
138 | for(i=0;i <= len; i++){
| ^~
[2/3] Linking target app/scrcpy
### (3). Execute the compilation result
[email protected]:~/scrcpy/scrcpy$ ./run build
INFO: scrcpy 1.19 <https://github.com/Genymobile/scrcpy>
../app/src/adb.c, ADB-CMD:adb push build/server/scrcpy-server /data/local/tmp/scrcpy-server.jar // First step ADB PUSH Server program to android Phone path and file name .
build/server/scrcpy-server: 1 file pushed. 2.7 MB/s (37330 bytes in 0.013s)
../app/src/adb.c, ADB-CMD:adb reverse localabstract:scrcpy tcp:27183
../app/src/adb.c, ADB-CMD:adb shell CLASSPATH=/data/local/tmp/scrcpy-server.jar\ // The second step ADB SHELL CLASSPATH Mode start android Mobile terminal program .
app_process / com.genymobile.scrcpy.Server 1.19 info 0 8000000 0 -1 false - true true 0 false false - - false
[server] INFO: Device: HUAWEI PRA-AL00X (Android 8.0.0)
../app/src/adb.c, ADB-CMD:adb reverse --remove localabstract:scrcpy
INFO: Renderer: opengl
INFO: OpenGL version: 3.3 (Compatibility Profile) Mesa 21.0.3
INFO: Trilinear filtering enabled
INFO: Initial texture: 1080x1920 // The third step adopt USB Way to run scrcpy Program success .
Part five WIFI Way to run scrcpy Results log
### open adb tcpip 5555 port
[email protected]:~/scrcpy/scrcpy$ adb tcpip 5555
### Link to mobile phone wifi The Internet
[email protected]:~/scrcpy/scrcpy$ adb connect 192.168.5.107:5555
connected to 192.168.5.107:5555
### adopt WIFI Link to... On your phone scrcpy The program runs
[email protected]:~/scrcpy/scrcpy$ ./build/app/scrcpy -s 192.168.5.107:5555 -b 5000000
INFO: scrcpy 1.19 <https://github.com/Genymobile/scrcpy>
../app/src/adb.c, ADB-CMD: adb -s 192.168.5.107:5555 push
/usr/local/share/scrcpy/scrcpy-server:...shed. 1.3 MB/s (37330 bytes in 0.028s)
../app/src/adb.c, ADB-CMD: adb -s 192.168.5.107:5555 reverse
error: more than one device/emulator
ERROR: "adb reverse" returned with value 1
WARN: 'adb reverse' failed, fallback to 'adb forward'
../app/src/adb.c, ADB-CMD: adb -s 192.168.5.107:5555 forward
../app/src/adb.c, ADB-CMD: adb -s 192.168.5.107:5555 shell CLASSPATH=/data/local/tmp/scrcpy-server.jar app_process / com.genymobile.scrcpy.Server 1.19 info 0 5000000 0 -1 true - true true 0 false false -
[server] INFO: Device: HUAWEI PRA-AL00X (Android 8.0.0)
../app/src/adb.c, ADB-CMD: adb -s 192.168.5.107:5555 forward
INFO: Renderer: opengl
INFO: OpenGL version: 3.3 (Compatibility Profile) Mesa 21.0.3
INFO: Trilinear filtering enabled
INFO: Initial texture: 1080x1920
Editor's note : No mapping , The fourth part of the program running log is very clear .
scrcpy The program startup logic is the result of the source code execution , It doesn't make any sense , Some readers may see relevant analysis on the Internet ,
Please refer to the actual output of this source code .
as for adb shell CLASSPATH function android Program description , Please search the relevant instructions on Zhihu by yourself .
边栏推荐
- Use of kotlin basic common sets list, set and map
- 自定义View
- MFS详解(五)——MFS元数据日志服务器安装与配置
- Not in the following list of legal domain names, wechat applet solution
- SSM框架整合--->简单后台管理
- Kotlin basic definition class, initialization and inheritance
- 楊輝三角形詳解
- [solution] camunda deployment process should point to a running platform rest API
- Dragon Boat Festival wellbeing, use blessing words to generate word cloud
- 线程相关点
猜你喜欢

Wechat applet: basic review

1+1 > 2, share creators can help you achieve
![[FAQs for novices on the road] understand program design step by step](/img/33/24ced00918bc7bd59f504cf1a73827.jpg)
[FAQs for novices on the road] understand program design step by step

杨辉三角形详解

Dart class inherits and implements mixed operators

JetPack - - - LifeCycle、ViewModel、LiveData

Echart histogram: stacked histogram displays value

MFS details (vii) - - MFS client and Web Monitoring installation configuration

Echart histogram: echart implements stacked histogram

App performance test: (III) traffic monitoring
随机推荐
欧姆龙平替国产大货—JY-V640半导体晶元盒读写器
自定义View —— 可伸展的CollapsExpendView
JS to realize bidirectional data binding
Custom view - extensible collapsexpendview
Uni app upload file
Notifyitemchanged flash back
[solution] camunda deployment process should point to a running platform rest API
【Kernel】驱动编译的两种方式:编译成模块、编译进内核(使用杂项设备驱动模板)
Fidde breakpoint interception
ADB shell content command debug database
Applet export (use) public function, public data
[JS] handwriting call(), apply(), bind()
Free screen recording software captura download and installation
Use of kotlin basic common sets list, set and map
Echart line chart: different colors are displayed when the names of multiple line charts are the same
347. top k high frequency elements heap sort + bucket sort +map
Uniapp (upload local pictures, preview pictures, convert Base64 format, upload audio files)
Wechat applet (function transfer parameters, transfer multiple parameters, page Jump)
Cross process two-way communication using messenger
Custom view