leng-yue / py-scrcpy-client

An easy to use python scrcpy client
https://leng-yue.github.io/py-scrcpy-client/
MIT License
283 stars 71 forks source link

按个人想法做了一些修复 #17

Closed Haskely closed 2 years ago

Haskely commented 2 years ago
  1. 修复Guide文档中的小错误
  2. 将UI中画面渲染与数据接收分离线程,避免因画面数据积压造成的画面延迟
  3. 将UI中翻转(filp)逻辑与画面数据接收逻辑分离,实现翻转效果的立即生效
leng-yue commented 2 years ago
  1. 感谢您发现文档的编写错误
  2. 理论上事件模式是不会阻塞的, 您有对画面延迟进行具体测试么, 谢谢
  3. 翻转结果实时生效可以通过修改 clientflip 来实现. https://github.com/leng-yue/py-scrcpy-client/blob/58259de745197adcaea8118fd466f743068848d2/scrcpy/core.py#L63
Haskely commented 2 years ago

1.感谢您发现文档的编写错误

不客气~

2.理论上事件模式是不会阻塞的, 您有对画面延迟进行具体测试么, 谢谢

我的确没有进行定量测试;此问题来源于之前偶发的使用体验。 关于理论上,通过研究源码,认为这里“事件模式”中的“事件”并非异步的,而是完全阻塞运行的:处理事件的逻辑运行时,client将无法接收下一帧。当然这里处理“事件”逻辑仅仅是将画面展示出来,开销很小,阻塞运行应该也无大碍,延迟的瓶颈不一定是这里,所以是自己想当然的修改。

关于“事件”并非异步:若要使这里的事件异步处理,可以单独开启一个事件处理thread,然后使用一个队列Quene作为中介实现 线程间通信。Client.__stream_loop(self) 仅负责把 frame 放入 Quene 中;事件处理thread负责从Quene 中取出frame进行处理逻辑。注意若处理逻辑很耗时,则Quene 会积压越来越多的待处理frame,所以也要单独实现丢弃处理。(自己这里https://github.com/leng-yue/py-scrcpy-client/pull/17/commits/5271d091b97d636cd8ac57a625be8bbe9ff01dfb#L178 每次只取最后一帧就相当于一种丢弃处理)

还有一个问题,Python存在全局解释器锁,所以这里的 线程Thread 本质上只是协程,对于计算密集型逻辑,还是可能存在阻塞问题。完美的异步需要开新进程,这就太复杂了,进程开销也有可能得不偿失。

翻转结果实时生效可以通过修改 client 的 flip 来实现

这里的确存在用户体验问题: 通过修改 client 的 flip 来实现,flip效果需要等待client推送下一帧才会生效:然而如果画面是静态的,处于压缩目的,client推送下一帧会有延迟(接近1000ms)。 测试方法:开启UI,保持画面不变,多次点击flip,会发现明显的延迟现象。

另一方面,从分工方式来讲,client逻辑上只需要做好接收视频流的工作即可,flip的逻辑应该属于UI本身的处理。

  1. 感谢您发现文档的编写错误
  2. 理论上事件模式是不会阻塞的, 您有对画面延迟进行具体测试么, 谢谢
  3. 翻转结果实时生效可以通过修改 clientflip 来实现. https://github.com/leng-yue/py-scrcpy-client/blob/58259de745197adcaea8118fd466f743068848d2/scrcpy/core.py#L63
leng-yue commented 2 years ago

感谢您的支持

  1. 第 181 行 循环运行造成的问题是 https://github.com/leng-yue/py-scrcpy-client/issues/3 也就是在没有图片推送的情况下, cpu 占用率会一直比较高. 正如您所说, 使用一个最大长度为 2-3 帧的队列可能更为合适, 我有空会进行修改 (当然你也可以直接 pr). 关于计算密集型的问题, 因为 opencv 是调用的 clib, 并不受到 GIL 的限制, 理论上是可以完全利用设备资源的.

  2. flip 最初的设计是因为 bluestack 的 bug 会导致屏幕翻转, 所以当时将 flip 作为了 client 的一部分. 仔细想想, bluestack 的 bug 确实不应该在 client 内部修复. 在这个 pr 合并后, 我会将 client 内部的 flip 删除.

说到实时翻转问题, 修改事件机制并不能解决实时翻转问题, 您提交的代码中实现实时翻转是依靠固定同步调用 on_frame 实现的.