3

I am in the process of creating a TCP remote desktop broadcasting application. (Something like Team Viewer or VNC) the server application will

1. run on a PC listening for multiple clients on one Thread
2. and on another thread it will record the desktop every second
3. and it will broadcast the desktop for each connected client.

i need to make this application possible to run on a connections with a 12KBps upload and 50KBps download DSL connection (client's and server).

so.. i have to reduce the size of the data/image i send per second.

i tried to reduce by doing the following.

I. first i send a Bitmap frame of the desktop and each other time i send only the difference of the previously sent frame.

II. the second way i tried was, each time i send a JPEG frame.

i was unsuccessful to send a JPEG frame and then each next time send the difference of the previously sent JPEG frame.

i tried using lzma compression (7zip SDK) for the when i was transmitting the difference of the Bitmap.

But i was unsuccessful to reduce the data into 12KBps. the maximum i was able to achieve was around 50KBps.

Can someone advice me an algorithm/procedure for doing this?

Mafahir Fairoze
  • 697
  • 2
  • 9
  • 21
  • try this one too http://cstheory.stackexchange.com/ – Ahmet Kakıcı Nov 04 '10 at 15:35
  • im a bit confused what would be the proper set of tags for this question in cstheory.stackexchange.com . – Mafahir Fairoze Nov 04 '10 at 15:49
  • Way back in the day, Laplink would somehow transfer UI objects such as menus and dialogs directly, rather than sending images of them. I have no idea how they did that, or if it even makes sense to do so with such graphical programs these days, but for super-low bandwidth, that may be an option. Really though, don't reinvent the wheel. UltraVNC has great options for reducing bandwidth down to nothing, includes display drivers (necessary for Vista and later) and screen capture options all in one. – Brad Nov 04 '10 at 16:18
  • @Brad: Display drivers are not needed if you are just capturing screenshots, though if you do that, then you need to do the rest of the work yourself. Now if VNC has an embeddable component, I would be interested in using it too... Display drivers are required/used for stuff like logged out users (there will be no program running to capture the screen) and elevation-related stuff (the yes/no dialog that pops up on Windows 7 for elevation, etc). – Gabriel Magana Nov 04 '10 at 16:27

1 Answers1

12

What you want to do is do what image compression formats do, but in a custom way (Send only the changes, not the whole image over and over). Here is what I would do, in two phases (phase 1: get it done, prove it works, phase 2: optimize)

Proof of concept phase

1) Capture an image of the screen in bitmap format

2) Section the image into blocks of contiguous bytes. You need to play around to find out what the optimal block size is; it will vary by uplink/downlink speed.

3) Get a short hash (crc32, maybe md5, experiment with this as well) for each block

4) Compress (don't forget to do this!) and transfer each changed block (If the hash changed, the block changed and needs to be transferred). Stitch the image together at the receiving end to display it.

5) Use UDP packets for data transfer.

Optimization phase

These are things you can do to optimize for speed:

1) Gather stats and hard code transfer speed vs frame size and hash method for optimal transfer speed

2) Make a self-adjusting mechanism for #1

3) Images compress better in square areas rather then contiguous blocks of bytes, as I explained in #2 of the first phase above. Change your algorithm so you are getting a visual square area rather than sequential blocks of lines. This square method is how the image and video compression people do it.

4) Play around with the compression algorithm. This will give you lots of variables to play with (CPU load vs internet access speed vs compression algorithm choice vs frequency of screen updates)

This is basically a summary of how (roughly) compressed video streaming works (you can see the similarities with your task if you think about it), so it's not an unproven concept.

HTH

EDIT: One more thing you can experiment with: After you capture a bitmap of the screen, reduce the number of colors in it. You can save half the image size if you go from 32 bit color depth to 16 bit, for example.

Gabriel Magana
  • 4,338
  • 24
  • 23
  • I have a few questions in phase 1, item 3 - i have never used hash, can u explain how should i use it. and in phase 1, item 4 - you say i must use UDP. whats the advantage you see. in phase 2, item 1 - u say use hash mathod for optimal transfer speed. how do i do that.. – Mafahir Fairoze Nov 04 '10 at 16:04
  • 1
    Hmm lots of explanation for those... At some point it will be better to study the underlying theory; but here goes, a hash is a checksum, like a summary number. It basically allows you to take a large number of data (pixels and their colors in this case) and generate a number (called a hash) based off it. If the number changes, then the underlying data changed. So you can compare a small amount of data (the hash value) to determine if the large data changed (the block of data). As for UDP vs TCP, it's because of speed. Read this for more info: http://www.gutgames.com/post/TCPIP-vs-UDP.aspx – Gabriel Magana Nov 04 '10 at 16:16