c++ - 需要有关 VNC 类应用程序中的图 block 缓存机制的建议

标签 c++ caching bitmap vnc

我正在开发“远程截屏”应用程序(就像 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/

相关文章:

c++ - 用户定义的转换是否将派生类类型转换为基类类型?

c++ - 未声明的标识符,超出范围? (使用 C++ 列表)

ruby - 如何在 ruby​​ 中缓存 Haml 模板

c# - 如何将 1D 字节数组转换为保存位图的 2D 字节数组?

java - 使用线程时 ImageView 不显示图像

c++ - sql::mysql::get_driver_instance() 找不到符号

c++ - 如何一次性复制一个文件夹中的大文件或小文件?

java - 使用 CachingConnectionFactory 和 DefaultMessageListenerContainer 中的缓存哪个更好?

c - Varnish 中的小写 url(内联 C)

图像或位图中的 C# 麦田圈