我正在开发“远程截屏”应用程序(就像 VNC 但不完全一样),我在其中通过网络传输更新的屏幕像素图 block 。我想实现缓存机制,我想听听你的建议...
这是我认为应该如何完成的。对于每个图 block 坐标,都有固定大小的堆栈(缓存),我可以在其中添加更新的图 block 。保存时,我会计算图 block 数据(即像素)的某种校验和(可能 CRC-16 就足够了,对吧?)。获取新图 block 时(来自桌面的新屏幕截图),我计算其校验和并与该图 block 坐标堆栈中的所有项目校验和进行比较。如果校验和匹配,我不会发送磁贴,而是发送特殊消息,例如“从位置 X 的缓存堆栈中获取图 block ”。这意味着我需要在服务器和客户端上拥有相同的缓存堆栈。
我的问题来了:
默认堆栈大小(深度)应该是多少?假设堆栈大小为 5,这意味着指定坐标的最后 5 个图 block 将被保存,屏幕像素分辨率的 5 倍将是总缓存大小。对于大屏幕,屏幕的原始 RGB 缓冲区约为。 5 兆字节,所以拥有 10 级堆栈意味着 50MB 缓存,对吗?那么缓存深度应该是多少呢?我想可能有 10 个,但需要您的建议。
在通过网络发送之前,我将图 block 压缩为 JPEG。我应该在压缩前实现 JPEG 图 block 或原始 RBG 图 block 的缓存吗?合理的选择是缓存原始图 block ,因为它可以避免对缓存中的图 block 进行不必要的 JPEG 编码。但是保存 RGB 像素将需要更大的缓存大小。那么最好的选择是什么 - 在压缩之前还是之后?
单独使用 CRC-16 校验和是否足以将新屏幕图 block 与缓存堆栈中的图 block 进行比较?我的意思是,当 CRC 匹配时,我是否应该另外对图 block 进行逐字节比较,还是多余的?碰撞概率是否低到可以丢弃?
总的来说,您如何看待我描述的方案?你会改变什么?任何类型的建议都将不胜感激!
最佳答案
我喜欢你解释一切的方式,这当然是一个很好的实现想法。
几个月前,我为一个类似的应用程序实现了类似的方法,现在正在寻找一些不同的方案,要么与之一起工作,要么取代它。
我使用的缓存堆栈大小与屏幕中显示的图 block 数量相等,并且不限制图 block 与上一个图 block 的相同位置匹配。我认为这在用户移动窗口时非常有帮助。缓存大小是处理能力、内存和带宽之间的权衡。缓存中的图 block 越多,您就可以在内存和处理成本上再次节省带宽。
我也使用了 CRC16,但这并不理想,因为当它命中缓存中的某些 CRC 时,它会产生非常奇怪的图像,这非常烦人但非常罕见。如果您在处理能力方面负担得起,最好的办法是逐像素匹配。就我而言,我不能。
缓存 JPEG 是节省内存的更好主意,因为如果我们从 JPEG 创建 BITMAP,就质量而言已经对其造成损害,我假设在两种情况下命中错误 CRC 的概率是相同的。就我而言,我使用的是 JPEG。
关于c++ - 需要有关 VNC 类应用程序中的图 block 缓存机制的建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6298771/