С# Лучший подход для отправки разницы экрана через сокет

Я работаю над проектом совместного использования экрана. Я отправляю только различия экрана через сокет, сравнивая предыдущий и фактический буфер. Это работает

Я отправляю клиенту от 8 до 9 кадров в секунду, используя Format16bppRgb555, чтобы уменьшить общий размер растрового изображения в байтах.

byte[] wholescreensize= new byte[1360 * 768 * 2];// Its around 2 Mb

Моя проблема в том, что при изменении полноэкранного режима.

Я получаю около 45-60 КБ изображения PNG, используя функцию ниже

45кб * 10 (FPS) = 450 кб

Можно уменьшить за пределы 45 кб.

Я не заинтересован в снижении FPS, поскольку это приложение для демонстрации экрана в реальном времени.

Сжатие JPEG или LZ4/GZIP также не имеет большого значения, так как изображение PNG уже сжато.

private void SendImgDiffToClient(byte[] contents,Rectangle rectangle)
{   

    //Converting Small Portion to Bitmap.Bcoz Image.FromStrem not working here error Parameter is not Valid
    byte[] byteArrayout = new byte[contents.Length];

    var bitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format16bppRgb555);
    var bitmap_data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format16bppRgb555);
    Marshal.Copy(contents, 0, bitmap_data.Scan0, byteArrayout.Length);
    bitmap.UnlockBits(bitmap_data);

    //Converting Small Bitmap to Png Byte Array and Sending to Client
    using (MemoryStream ms = new MemoryStream())
    { 
        Image msImage = (Image)bitmap;
        msImage.Save(ms, ImageFormat.Png);

        msImage.Dispose();
        byteArrayout = ms.ToArray();
    }  

    SendtoClient(byteArrayout);
}

Мои поиски - это лучший подход к уменьшению байтов в таком сценарии.


person Azar Shaikh    schedule 05.03.2018    source источник
comment
PNG — это сжатие без потерь. Если вы хотите уменьшить его еще больше, используйте сжатие с потерями (JPG), межкадровое сжатие (mpg) и/или уменьшите частоту кадров.   -  person Manfred Radlwimmer    schedule 05.03.2018
comment
Нет хорошего способа сделать это, всегда слишком медленно для современных размеров монитора. Используйте для этого встроенную поддержку ОС, сервисы удаленного рабочего стола google c# для поиска хитов. Он получает свою скорость за счет кодирования команд видеодрайвера вместо пикселей.   -  person Hans Passant    schedule 05.03.2018
comment
@HansPassant, я уже изучаю это. я не получаю никакого подходящего решения для этого. попробовал это, но безуспешно улучшить способы"> stackoverflow.com/questions/31543940/   -  person Azar Shaikh    schedule 05.03.2018
comment
Ну, я же говорил тебе. Используйте РДП.   -  person Hans Passant    schedule 05.03.2018
comment
я использую протокол vnc здесь. к сожалению не могу переключиться. Клиент общается по протоколу vnc   -  person Azar Shaikh    schedule 05.03.2018
comment
Здесь вы столкнетесь с двумя проблемами. Если вы обрабатываете изображения, чтобы сделать их меньше, вы столкнетесь с медленными обновлениями изображений из-за обработки на стороне клиента. Если вы отправите необработанные изображения в программу просмотра, они столкнутся с медлительностью сети. Изображения должны быть в реальном времени? Как насчет задержки в несколько секунд?   -  person Baaleos    schedule 05.03.2018
comment
@Baaleos Все в порядке с задержкой в ​​​​несколько секунд, но, к сожалению, я не получаю никакого решения.   -  person Azar Shaikh    schedule 05.03.2018
comment
попробуйте использовать base64 для отправки. это может уменьшить размер   -  person sLw    schedule 05.03.2018
comment
@sLowDowN увеличивает размер байтов   -  person Azar Shaikh    schedule 05.03.2018
comment
Возможно, вы сможете найти компромисс между скоростью и пропускной способностью, разделив данные кадра на части. Например: Создайте 10-секундные данные кадра - обработайте их в MP4 или AVI с хорошим сжатием - отправьте их клиенту. Попросите клиента сохранить эти 10 секунд буферизованных данных, а затем воспроизвести их. Обработка отдельных кадров на самом деле не будет работать для отправки различий кадров, так как вам нужно иметь предыдущий кадр в памяти для вычисления «разниц». Если вы используете видеокодек для обработки нескольких секунд кадров, вы, вероятно, можете избавить себя от проблем, связанных с обработкой кадров.   -  person Baaleos    schedule 05.03.2018
comment
Когда полноэкранный режим изменен, вы больше не должны разбивать данные на фрагменты, просто отправляйте полное изображение. Кроме того, вы можете уменьшить размер фрагмента, используя .PixelData (если я правильно помню имя, без заголовков и всего этого джаза, что также сократит время на повторную сборку изображения, поскольку оно уже будет в лучшем формате для «вставки»). в нужных местах, полоска за полоской.   -  person Alexandru Clonțea    schedule 07.03.2018
comment
На самом деле получаются маленькие локти, а именно пиксельные данные. Также убедитесь, что вы не используете формат, использующий альфа-канал!   -  person Alexandru Clonțea    schedule 07.03.2018
comment
Little cubits == Lockbits автозамена (мобильный). Сжатие может быть не сжатием изображения, возможно, вы должны отправить diff, но вам нужна какая-то приоритетная очередь, чтобы сделать недействительным рендеринг региона до последней версии ... поток мыслей здесь, я поближе посмотрю сегодня вечером / на выходных. Ганс Пассант дает здесь лучший совет, попробуйте использовать готовый, сложный предмет!   -  person Alexandru Clonțea    schedule 07.03.2018
comment
Спасибо @AlexandruClonțea   -  person Azar Shaikh    schedule 07.03.2018
comment
github.com/humphd/VncSharp   -  person Alexandru Clonțea    schedule 07.03.2018
comment
@AlexandruClonțea vncsharp — это клиентская реализация vnc. У меня возникает проблема на стороне сервера vnc для отправки обновления буфера разницы изображений   -  person Azar Shaikh    schedule 07.03.2018
comment
Тогда вас может вдохновить github.com/T1T4N/NVNC :)   -  person Alexandru Clonțea    schedule 07.03.2018
comment
1. используйте UDP для этих целей 2. вы можете попробовать один из двух вариантов - вычислить разницу с вашим собственным кодом и отправить только заархивированные различия - вы можете попробовать отправить видеопоток h.264 (который будет вычислять различия, сжимать и так далее при декодировании).   -  person Igor Gnedysh    schedule 13.03.2018
comment
MJPEGStream — это ответ   -  person Mauro Sampietro    schedule 13.03.2018
comment
Я сделал это, используя вызовы DirectX и Win32 sdk на С#. Мне удалось захватить значительно выше 10 кадров в секунду. Я предлагаю несколько поисков по этим ключевым словам. В этой статье используется C. Вы можете легко упорядочить вызовы C#. codeproject.com/Articles/5051/   -  person tatmanblue    schedule 13.03.2018


Ответы (1)


Потоковое видео — это, по сути, то, чем вы занимаетесь; и современные алгоритмы сжатия видео имеют множество улучшений. Возможно, они могут отслеживать или перемещать артефакт или иным образом искажать указанный артефакт как часть своей функциональности. Возможно, они могут передавать данные в прогрессивной манере построения, чтобы статические элементы в конечном итоге приобретали больше деталей (аналогично прогрессивным изображениям jpeg). Они делают множество вещей одновременно. Вы можете попытаться исследовать их дальше и черпать из них вдохновение, или вы можете выбрать и использовать один из них.

Это означает, что многие люди здесь, кажется, предпочитают решение с использованием легкодоступной библиотеки сжатия видео. Особенно, если вы беспокоитесь о пропускной способности потоковой передачи.

Если вы не хотите использовать существующую видеотеку, вам нужно решить, сколько усилий вы хотите приложить, а не насколько неаккуратно вы хотите быть с потреблением большей пропускной способности, чем в противном случае необходимо.

person Greg    schedule 13.03.2018