需要有关类似 VNC 的应用程序中的图块缓存机制的建议
我正在开发“远程截屏”应用程序(就像 VNC 但不完全一样),我在其中通过网络传输更新的屏幕像素图块。我想实现缓存机制,并且想听听您的建议...
我认为应该这样做。对于每个图块坐标,都有固定大小的堆栈(缓存),我在其中添加更新的图块。保存时,我计算图块数据(即像素)的某种校验和(可能 CRC-16 就足够了,对吧?)。当获取新图块时(来自桌面的新屏幕截图),我计算其校验和并与该图块坐标堆栈中的所有项目校验和进行比较。如果校验和匹配,则不发送图块,而是发送特殊消息,例如“从位置 X 处的缓存堆栈获取图块”。这意味着我需要在服务器和客户端上拥有相同的缓存堆栈。
我的问题是:
默认堆栈大小(深度)应该是多少?假设堆栈大小为 5,这意味着将保存指定坐标的最后 5 个图块,并且屏幕像素分辨率的 5 倍将是总缓存大小。对于大屏幕,屏幕的原始 RGB 缓冲区约为。 5 MB,所以拥有 10 级堆栈意味着 50 MB 缓存,对吗?那么缓存深度应该是多少呢?我想可能是 10,但需要您的建议。
在通过网络发送之前,我将图块压缩为 JPEG。我应该在压缩前实现 JPEG 图块或原始 RBG 图块的缓存吗?逻辑选择是缓存原始切片,因为这样可以避免对缓存中找到的切片进行不必要的 JPEG 编码。但保存 RGB 像素将需要更大的缓存大小。那么最好的选择是什么 - 压缩之前还是压缩之后?
仅 CRC-16 校验和就足以将新屏幕图块与缓存堆栈中的图块进行比较吗?我的意思是,当 CRC 匹配时,我是否应该另外对图块进行逐字节比较,还是多余的?冲突概率是否低到足以被丢弃?
总的来说,您对我描述的方案有何看法?你会改变什么?如有任何建议,我们将不胜感激!
I'm developing "remote screencasting" application (just like VNC but not exactly), where I transfer updated tiles of screen pixels over the network. I'd like to implement the caching mechanism, and I'd like to hear your recommendations...
Here is how I think it should be done. For each tile coordinate, there is fixed size stack (cache) where I add updated tiles. When saving, I calculate some kind of checksum (probably CRC-16 would suffice, right?) of the tile data (i.e. pixels). When getting new tile (from the new screenshot of desktop), I calculate its checksum and compare to all items checksums in the stack of that tile coordinate. If the checksum matches, instead of sending the tile I send the special message e.g. "get tile from cache stack at position X". This means I need to have identical cache stacks on the server and on the client.
Here comes my questions:
What should be the default stack size (depth)? Say if stack size is 5, this means last 5 tiles of specified coordinates will be saved, and 5 times the resolution of screen pixels will be the total cache size. For big screens raw RGB buffer of screen will be approx. 5 megabytes, so having 10-level stack means 50MB cache, right? So what should be the cache depth? I think maybe 10 but need your suggestions.
I'm compressing the tiles into JPEG before sending over network. Should I implement caching of JPEG tiles, or raw RBG tiles before compression? Logical choice would be caching raw tiles as it would avoid unnecessary JPEG encoding for the tiles that would be found in cache. But saving RGB pixels will require much bigger cache size. So what's the best option - before or after compression?
Is CRC-16 checksum alone enough for comparing new screen tiles with the tiles in cache stack? I mean should I additionally make byte-by-byte comparison for the tiles when CRC matches, or is it redundant? Is the collision probability low enough to be discarded?
In general, what do you think about the scheme I described? What would you change in it? Any kind of suggestions would be appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我喜欢你解释一切的方式,这当然是一个实施的好主意。
几个月前,我对类似的应用程序实施了类似的方法,现在正在寻找一些不同的方案,要么与其配合使用,要么取代它。
我使用的缓存堆栈大小等于屏幕中存在的图块数量,并且没有限制图块与前一个图块的相同位置匹配。我认为当用户移动窗口时它非常有帮助。缓存大小是处理能力、内存和带宽之间的权衡。缓存中的切片越多,您就可以在内存和处理成本上再次节省更多的带宽。
我也使用了 CRC16,但这并不理想,因为当它命中缓存中的某些 CRC 时,它会生成一个非常奇怪的图像,这非常烦人,但非常罕见。如果您的处理能力能够承受的话,最好的办法就是逐像素匹配。就我而言,我不能。
缓存 JPEG 是节省内存的更好主意,因为如果我们从 JPEG 创建 BITMAP,就质量而言已经对其造成了损害,我假设在两种情况下命中错误 CRC 的概率是相同的。就我而言,我使用的是 JPEG。
I like the way you explained everything, this is certainly a nice idea to implement.
I implemented the similar approach for a similar application couple of months ago, Now looking for some different schemes either work along with it or replace it.
I used the cache stack size equal number of tiles as present in a screen and didn't restrict the tile to be matched with same location previous tile. I assume it is very helpful while user is moving a window. Cache size is a trade-off between processing power , memory and bandwidth. The more tiles you have in cache the more you may save the bandwidth again on the cost of memory and processing.
I used CRC16 too but this is not ideal to implement as when it hits some CRCs in cache it produces a very odd image, which was quite annoying but very rare. Best thing is the match pixel by pixel if you can afford it in-terms of processing power. In my case I couldn't.
Caching JPEG is a better idea to save the memory, because if we create BITMAP from JPEG the damage has already been done to it in-terms of quality, I assume the probability of hitting wrong CRC is the same in both cases. I, in my case, used JPEG.
我会使用更快的哈希算法。例如 murmur2 或 Jenkins。它保证了更好的独特性。
有关缓存的示例,请参阅 Spice 远程协议 (www.spice-space.org)。
缓存应该尽可能大(在客户端或中间代理中)。
I'd use a faster hash algorithm. murmur2 or Jenkins for example. It promises much better uniqueness.
See Spice remote protocol (www.spice-space.org) for example of caching.
The cache should be as big as it can be (on the client, or in an intermediate proxy).
您可以查看 x11vnc 的缓存实现。
You might check out x11vnc's cache implementation.