scrcpy 源代码渲染逻辑整理

背景

自己学习scrcpy自己写的协同工具遇到了一些问题,所以分析了一下源代码,结果我出现的问题只是参数搞错了。

分析

  1. stream.c
    a. run_stream 创建线程,不停读取数据,然后投递接受的packet,然后投递数据
    b. stream_parse 解析收到数据packet
    c. push_packet_to_sinks 投递数据到
  2. decoder.c
    a. decoder_init 注册解码函数
    b. decoder_push 解析推过来的packet
    c. push_frame_to_sinks 推送得到frame 数据帧
  3. screen.c
    a. sc_screen_init 创建窗口
    b. 绑定frame处理函数
    c. sc_screen_frame_sink_push 投递从decoder解码的数据
  4. video_buffer.c
    a. sc_video_buffer_init 主要初始化队列和一些信号量
    b. sc_video_buffer_start 创建线程,不停读取队列,
    c. run_buffering 不停读取队列帧,判断是否超时,然后进行投递。sc_video_buffer_on_new_frame 通过这个回调到sceen.c 对象里面。
  5. screen.c
    a. sc_video_buffer_on_new_frame 通过 SDL_PushEvent 获取当前数据的

    总结


    这种c代码看起来还是很爽,几个对象抽象挺好,我自己写代码只封装解码层,网络层,SDL处理层,事件通知层。
    scrcpy 队列我没有感受他的好处,开始因为我的卡是没有这个帧的队列,后面发现,根本不是这么一会事情,事情情况渲染速度远远大于传送网络传送过来帧,我自己也实现一个简单队列,检测到帧堆积,直接丢弃,只显示最新的帧,结果从来就没有丢弃。
    scrcpy app 最核心SurfaceControl 反射实现,其他的模拟可以借鉴adb 命令实现代码实现,不过这个SurfaceControl 有人分析android 核心代码可以找到实现,但我自己看了一下貌似没有看懂,直接就拿scrcpy反射实现,其他几个控制命令都是我自己实现,更加简单明了,它是实现几个点击滚动太过于复杂了。

format.setInteger(MediaFormat.KEY_FRAME_RATE, 60);

这个代表帧率,这个Scrcpy其实动态的,这个跟延迟有一定关系,但我之前设置错参数出现反复点击一个表情会出现延迟,然后把这个设置120就延迟了,手机FPS是60.

format.setLong(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, REPEAT_FRAME_DELAY_US); // µs

这个影响到延迟的,这个给我感觉保持一直采集有数据,之前就是我把这个设置错了,导致快速点击输入表情时候会出现明显的延迟。

format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
这个跟画面清晰度有关系,类似直播高清,蓝光4M 这些。

会删除掉复制tmp的jar包

我开始到目录找了好久,没有好到文件,但命令确实复制到tmp

我不知道scrcpy 用OS.write 有什么好处,我直接用websocket通信,也不走转发,我自己用Websocket跑的时候效果差不多,协议直接用JSON格式就可以了,也不用字节解析,视频流原始传递,这个才是消耗流量的地方,控制的消耗不了多少流量。

scrcpy 我觉得待补充的功能

  • 蓝牙【貌似分支有了】
  • 远程控制【我自己目前这种模式就可以支持远程,我目的就是远程控制手机】
  • 后台运行 【提供增强功能,可以给APP使用,市面已经这样子APP】
  • 输入法增强 【我不知道目前这个实现了没有】
  • 控制栏 【我自己用win32 实现了,感受最原始界面开发】
  • 鼠标点击录制【用来做脚本,结合辅助服务最好,不知道能不能直接反射使用,开启辅助是可以做到】,这个只要做到基本就是无敌了软件。
  • 鼠标模拟增强 【目前鼠标的模拟,如果玩游戏可以检测出来,应该跟属性有关系,这种要做专门优化】

自己开发的软件应该远程控制+手机增强功能,给自己开发用的软件。

app process 其实能做很多东西,
以后想到什么再补充吧。