scrcpy 一个Android手机的开源投屏工具,显示高清流畅,而且可以用电脑鼠标控制手机,极低延迟,有人甚至用来远控玩手机游戏。
开源的好软件,想在开源的基础上增加点功能,做出自己的小工具。想起来很不错,但现在的开源软件,几乎都是Linux编译环境,Windows下面的也基本上是mingw,msys2等虚拟Linux编译环境,可以直接MSVC环境编译的很少。还是比较习惯vs开发环境,所以想试下改到VS编译。折腾了两天,终于编译通过。
总体来说,难度不是很大,主要因为整个项目比较小,移植差异不是很大。要是大的项目建议还是算了吧。把过程写下来以供参考。
1.依赖的库ffmpeg,sdl2都有windows VC版本的库,网上都很容易下载。
ffmpeg x64 版本 :
https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-4.1.3-win64-dev.zip
https://ffmpeg.zeranoe.com/builds/win64/shared/ffmpeg-4.1.3-win64-shared.zip
sdl2 x64版本:
https://www.libsdl.org/release/SDL2-devel-2.0.9-VC.zip
https://www.libsdl.org/release/SDL2-2.0.9-win32-x64.zip
2.头文件
(1) #include
#include
#include
(2)#include "config.h" 直接注释掉。
(3)#include
#include
(4)#include
#include
3.数据类型:
未定义的数据类型:ssize_t
解决办法:全部替换为 int
4.宏定义:
有些宏定义在编译配置文件中定义,如mson.build中定义:
# the default client TCP port for the "adb reverse" tunnel
# overridden by option --port
conf.set('DEFAULT_LOCAL_PORT', '27183')
# the default max video size for both dimensions, in pixels
# overridden by option --max-size
conf.set('DEFAULT_MAX_SIZE', '0') # 0: unlimited
# the default video bitrate, in bits/second
# overridden by option --bit-rate
conf.set('DEFAULT_BIT_RATE', '8000000') # 8Mbps
在scrcpy.h中增加定义:
#define DEFAULT_LOCAL_PORT 27183
#define DEFAULT_MAX_SIZE 0
#define DEFAULT_BIT_RATE 8000000
5.vc 不支持的GCC特性:
(1).可变长数组:
const char *cmd[len + 4];
简单改为固定长度数组:const char *cmd[250];
(2)结构体初始化:
struct args args = {
.serial = NULL,
.crop = NULL,
.record_filename = NULL,
.record_format = 0,
.help = false,
.version = false,
.show_touches = false,
.port = DEFAULT_LOCAL_PORT,
.max_size = DEFAULT_MAX_SIZE,
.bit_rate = DEFAULT_BIT_RATE,
.always_on_top = false,
.no_control = false,
.no_display = false,
.turn_screen_off = false,
.render_expired_frames = false,
};
改为:
struct args args = {
NULL,//.serial = NULL,
NULL,//.crop = NULL,
NULL,//.record_filename = NULL,
(recorder_format)0,//.record_format = 0,
false,//.fullscreen;
false,//.no_control = false,
false,//.no_display = false,
false,//.help = false,
false,//.version = false,
false,//.show_touches = false,
DEFAULT_LOCAL_PORT,//.port = DEFAULT_LOCAL_PORT,
DEFAULT_MAX_SIZE,//.max_size = DEFAULT_MAX_SIZE,
DEFAULT_BIT_RATE, //.bit_rate = DEFAULT_BIT_RATE,
false,//.always_on_top = false,
false,//.turn_screen_off = false,
false//.render_expired_frames = false,
};
(3)多行宏定义带返回值
#define cbuf_take(PCBUF, PITEM) \
({ \
bool ok = !cbuf_is_empty(PCBUF); \
if (ok) { \
*(PITEM) = (PCBUF)->data[(PCBUF)->tail]; \
(PCBUF)->tail = ((PCBUF)->tail + 1) % cbuf_size_(PCBUF); \
} \
ok; \
})
解决办法:改为
#define cbuf_take(PCBUF, PITEM,ok) \
{ \
ok = !cbuf_is_empty(PCBUF); \
if (ok) { \
*(PITEM) = (PCBUF)->data[(PCBUF)->tail]; \
(PCBUF)->tail = ((PCBUF)->tail + 1) % cbuf_size_(PCBUF); \
} \
}
相应的调用也要改改:
bool non_empty = cbuf_take(&controller->queue, &msg);
改为:
bool non_empty;
cbuf_take(&controller->queue, &msg,non_empty);
还有些小问题(比如头文件库文件路径),不难解决。