3

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!

TX_
  • 83
  • 1
  • 5

3 Answers3

1

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.

jonsca
  • 10,218
  • 26
  • 54
  • 62
1

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).

Yaniv
  • 11
  • 1
0

You might check out x11vnc's cache implementation.

genpfault
  • 51,148
  • 11
  • 85
  • 139