3

我正在开发“远程截屏”应用程序(就像 VNC 但不完全一样),我在其中通过网络传输更新的屏幕像素图块。我想实现缓存机制,我想听听你的建议......

这是我认为应该这样做的方式。对于每个图块坐标,都有固定大小的堆栈(缓存),我在其中添加更新的图块。保存时,我计算平铺数据(即像素)的某种校验和(可能 CRC-16 就足够了,对吗?)。获取新图块时(来自桌面的新屏幕截图),我计算其校验和并与该图块坐标堆栈中的所有项目校验和进行比较。如果校验和匹配,而不是发送瓦片,我发送特殊消息,例如“从位置 X 的缓存堆栈获取瓦片”。这意味着我需要在服务器和客户端上拥有相同的缓存堆栈。

我的问题来了:

  • 默认堆栈大小(深度)应该是多少?假设堆栈大小为 5,这意味着将保存指定坐标的最后 5 个图块,屏幕像素分辨率的 5 倍将是总缓存大小。对于大屏幕,屏幕的原始 RGB 缓冲区将约为。5 MB,所以拥有 10 级堆栈意味着 50MB 缓存,对吗?那么缓存深度应该是多少呢?我想可能有 10 个,但需要你的建议。

  • 在通过网络发送之前,我将图块压缩为 JPEG。我应该在压缩之前实现 JPEG 切片或原始 RBG 切片的缓存吗?逻辑选择是缓存原始切片,因为它可以避免对缓存中找到的切片进行不必要的 JPEG 编码。但是保存 RGB 像素需要更大的缓存大小。那么最好的选择是什么——压缩之前还是之后?

  • CRC-16 校验和是否足以将新屏幕图块与缓存堆栈中的图块进行比较?我的意思是,当 CRC 匹配时,我应该另外对瓦片进行逐字节比较,还是多余的?碰撞概率是否低到足以被丢弃?

  • 总的来说,您如何看待我描述的方案?你会在其中改变什么?任何形式的建议将不胜感激!

4

3 回答 3

1

我会使用更快的哈希算法。例如 murmur2 或 Jenkins。它承诺更好的独特性。有关缓存的示例,请参见 Spice 远程协议 (www.spice-space.org)。缓存应尽可能大(在客户端或中间代理中)。

于 2012-02-21T11:55:22.513 回答
1

我喜欢你解释一切的方式,这当然是一个好主意。

几个月前,我为类似的应用程序实施了类似的方法,现在正在寻找一些不同的方案,要么与之一起工作,要么替换它。

我使用的缓存堆栈大小与屏幕中存在的图块数量相同,并且没有限制图块与前一个图块的相同位置匹配。我认为这在用户移动窗口时非常有用。缓存大小是处理能力、内存和带宽之间的权衡。缓存中的切片越多,您就可以在内存和处理成本上再次节省带宽。

我也使用了 CRC16,但这并不理想,因为当它在缓存中遇到一些 CRC 时会产生一个非常奇怪的图像,这很烦人但非常罕见。最好的事情是逐像素匹配,如果你能负担得起就处理能力而言。就我而言,我不能。

缓存 JPEG 是节省内存的更好主意,因为如果我们从 JPEG 创建 BITMAP,就质量而言已经对其造成了损害,我假设在这两种情况下命中错误 CRC 的概率是相同的。我,就我而言,使用JPEG。

于 2011-07-29T12:07:36.397 回答
0

您可以查看x11vnc 的缓存实现

于 2011-06-09T22:10:13.520 回答