Sla*_*shy 17 c# sockets performance
最近我一直在做一个简单的屏幕共享程序.
实际上,该程序可以TCP protocol
使用桌面复制API - 一种很酷的服务,支持非常快速的屏幕捕获,还提供有关MovedRegions
(仅改变其在屏幕上的位置但仍然存在的UpdatedRegions
区域)和(更改区域)的信息.
桌面复制有2个重要属性 - 2个字节数组,一个数组previouspixels
和一个NewPixels
数组.每4个字节代表RGBA形式的一个像素,例如,如果我的屏幕是1920 x 1080,则缓冲区大小为1920 x 1080*4.
以下是我的策略的重要亮点
从现在开始,我遍历UpdatedRegions(它是一个矩形数组),我发送区域边界和Xo'r像素,如下所示:
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]);
}
}
}
Run Code Online (Sandbox Code Playgroud)'writer'是我编写的'QuickBinaryWriter'类的一个实例(只是为了再次重用相同的缓冲区).
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]);
}
}
Run Code Online (Sandbox Code Playgroud)
从许多方面来看,我已经看到发送的数据非常庞大,有时对于单帧更新,数据可能达到200kb(压缩后!).说实话 - 200kb真的没什么,但如果我想顺畅地流式传输屏幕并且能够以高Fps速率观看,我将不得不对此进行一些工作 - 以最小化网络流量和带宽使用.
我正在寻找建议和创意,以提高计划的效率 - 主要是在网络部分发送的数据(通过以其他方式或任何其他方式包装)我会感激任何帮助和想法.谢谢.
Vik*_*ram 18
对于屏幕为1920 x 1080,具有4字节颜色,您每帧大约需要8 MB.使用20 FPS,您可以达到160 MB/s.因此从8 MB到200 KB(4 MB/s @ 20 FPS)是一个很大的改进.
我想提醒你注意我不确定你关注的某些方面,希望它有所帮助.
newpixels
和之间发送差异previouspixels
.不用说原始屏幕和差异屏幕都将被LZ4压缩/解压缩.如果你使用一些有损算法来压缩差异,你应该经常发送完整的数组而不是diff.上述想法可以一个接一个地应用,以获得更好的用户体验.最终,它取决于您的应用程序和最终用户的具体情况.
编辑:
颜色量化可用于减少用于颜色的位数.以下是颜色量化的具体实现的一些链接
通常,量化的颜色存储在调色板中,并且只有该调色板的索引被提供给解码逻辑
归档时间: |
|
查看次数: |
7986 次 |
最近记录: |