Lately I have been working on a simple screen sharing program.
Actually the program works on a TCP protocol
and uses the Desktop duplication API- a cool service that support very fast screen capturing and also provide information about MovedRegions
(areas that only changed their position on the screen but still exist) and UpdatedRegions
(changed areas).
The Desktop duplication has 2 improtant properties-2 byte arrays an array for the previouspixels
and a NewPixels
array. Every 4 bytes represent a pixel in the RGBA form so for example if my screen is 1920 x 1080 the buffer size is 1920 x 1080 * 4.
Below are the important highlights of my strategy
From now on, I iterate over the UpdatedRegions (it's a rectangles array) and I send the regions bounds and Xo'r the pixels in it something like this:
writer.Position = 0;
var n = frame._newPixels;
var w = 1920 * 4; //frame boundaries.
var p = frame._previousPixels;
foreach (var region in frame.UpdatedRegions)
{
writer.WriteInt(region.Top);
writer.WriteInt(region.Height);
writer.WriteInt(region.Left);
writer.WriteInt(region.Width);
for (int y = region.Top, yOffset = y * w; y < region.Bottom; y++, yOffset += w)
{
for (int x = region.Left, xOffset = x * 4, i = yOffset + xOffset; x < region.Right; x++, i += 4)
{
writer.WriteByte(n[i] ^ p[i]); //'n' is the newpixels buffer and 'p' is the previous.xoring for differences.
writer.WriteByte(n[i+1] ^ p[i+1]);
writer.WriteByte(n[i + 2] ^ p[i + 2]);
}
}
}
'writer' is a instance of 'QuickBinaryWriter' class i wrote (simply to reuse the same buffer again).
public class QuickBinaryWriter
{
private readonly byte[] _buffer;
private int _position;
public QuickBinaryWriter(byte[] buffer)
{
_buffer = buffer;
}
public int Position
{
get { return _position; }
set { _position = value; }
}
public void WriteByte(byte value)
{
_buffer[_position++] = value;
}
public void WriteInt(int value)
{
byte[] arr = BitConverter.GetBytes(value);
for (int i = 0; i < arr.Length; i++)
WriteByte(arr[i]);
}
}
From many measures, I've seen that the data sent is really huge, and sometimes for a single frame update the data could get up to 200kb (after compression!). Lets be honest-200kb is really nothing,but if i want to smoothly stream the screen and be able to watch in high Fps rate i would have to work on this a little bit - to minimize the network traffic and the bandwidth usage.
I'm looking for suggestion and creative ideas to improve the efficiency of the program- mainly the data sent on the network part (by packing it in other ways or any other idea)i'll appreciate any help and ideas.Thanks.
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.
Compared to other languages—like Java, PHP, or C#—C is a relatively simple language to learn for anyone just starting to learn computer programming because of its limited number of keywords.
Originally Answered: What is the full form of C ? C - Compiler . C is a general-purpose, high-level language that was originally developed by Dennis M. Ritchie to develop the UNIX operating system at Bell Labs. C was originally first implemented on the DEC PDP-11 computer in 1972.
For your screen of 1920 x 1080, with 4 byte color, you are looking at approximately 8 MB per frame. With 20 FPS, you have 160 MB/s. So getting from 8 MB to 200 KB (4 MB/s @ 20 FPS) is a great improvement.
I would like to get your attention to certain aspects that I am not sure you are focusing on, and hopefully it helps.
newpixels
and previouspixels
. Needless to say the the original screen and the diff screen will all be LZ4 compressed/decompressed. Every so often you should send the full array instead of the diff, if you use some lossy algorithm to compress the diff.The ideas above can be applied one on top of the other to get a better user experience. Ultimately, it depends on the specifics of your application and end-users.
EDIT:
Color Quantization can be used to reduce the number of bits used for a color. Below are some links to concrete implementations of Color Quantization
Usually the quantized colors are stored in a Color Palette and only the index into this palette is given to the decoding logic
Slashy,
Since you are using a high res frames and you want a good frame rate you're likely going to be looking at H.264 encoding. I've done some work in HD/SDI broadcast video which is totaly dependent on H.264, and a little now moving to H.265. Most of the libraries used in broadcast are written in C++ for speed.
I'd suggest looking at something like this https://msdn.microsoft.com/en-us/library/windows/desktop/dd797816(v=vs.85).aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With