Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];

Вниз

Снимок экрана   Найти похожие ветки 

 
Nic2   (2004-09-22 17:41) [0]

Здравствуйте Мастера.
Пишу программу, которая передает снимки моего экрана на др. машину по сети и там их отображает (короче просмотр экрана удаленной машины). Делать это пытаюсь 24 кадра в сек., пакуя снимки в JPEG Проблема такая: упаковка в JPEG длится долго, а по сему получается максимум 8 кадров в секунду. Можно ли как-то увеличить кол-во кадров в секунду.
Код:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
procedure TFORM1.CopyScrMy();
var
ScrBitmap: TBitmap;
jpg: TJPEGImage;
begin
    DC := GetDC(0);
    BInfo.bmiHeader.biSize := sizeof(tagBITMAPINFOHEADER);
    BInfo.bmiHeader.biWidth := 1024;
    BInfo.bmiHeader.biHeight := 768;
    BInfo.bmiHeader.biPlanes := 1;
    BInfo.bmiHeader.biBitCount := 24;
    BInfo.bmiHeader.biCompression := BI_RGB;
    binfo.bmiHeader.biSizeImage:=0;
    ScrBitmap := TBitmap.Create();
    ScrBitmap.Handle := CreateDIBSection(Canvas.Handle, BInfo, DIB_RGB_COLORS, Scr, 0, 0);
    bitblt(ScrBitmap.Canvas.Handle,0,0,1024,768,DC,0,0,srccopy);
    ScrBitmap.ScanLine[1];
try
  if not ScrBitmap.Empty then
   begin
    ms:=TMemoryStream.Create;
    jpg := TJPEGImage.Create;
    jpg.Performance:=jpBestspeed;
    jpg.PixelFormat:=jf8Bit;
    jpg.Scale:=jsHalf;
    jpg.CompressionQuality:=50;
    jpg.Compress;
    jpg.Assign(ScrBitmap);
    ScrBitmap.Assign(jpg);
    jpg.SaveToStream(ms);
    ms.Position:=0;
    try
     Socket.PostIt(ms);
    except
    end;
   end;
finally
 ms.Clear;
 b.Free;
 jpg.Free;
 DeleteDC(DC);
 SCRBitmap.Free;
end;
end;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Заранее спасибо.


 
WondeRu ©   (2004-09-23 13:02) [1]

а пробуй просто упаковывать! используй zlib (F1 in Delphi)


 
Multy   (2004-09-23 14:50) [2]

А почему не воспользоватся уже готовым совтом?


 
Анонимщик ©   (2004-09-23 15:24) [3]

А сколько кадров ты в состоянии сжать за секунду?


 
Mihey_temporary ©   (2004-09-23 15:26) [4]

Попробуй использовать глобальные переменные, например, для Jpg, т.е. не создавать и удалять каждый раз.


 
Nic2   (2004-09-24 14:40) [5]

<<А почему не воспользоватся уже готовым совтом?>>
Мне нужно делать просмотр в определенные моменты времени, которые определяет моя программа, но это не главное, в последствии я собираюсь организовать просмотр экранов 4-х машин (ну хотябы попробую...).

<<А сколько кадров ты в состоянии сжать за секунду?>>
Если Вы имеете в виду сколько я хотел бы видеть кадров в секунду, то 15-20 (ну в идеале естественно 24).

<<Попробуй использовать глобальные переменные, например, для Jpg, т.е. не создавать и удалять каждый раз.>>
Это я привел один из вариантов, а вообще я пробовал и глобальные переменные, и создавал все по загрузке проги (а убивал по завершению). Все бестолку-7-8кадров.

Спасибо всем кто отозвался.


 
Анонимщик ©   (2004-09-24 15:19) [6]

<<А сколько кадров ты в состоянии сжать за секунду?>>
Если Вы имеете в виду сколько я хотел бы видеть кадров в секунду, то 15-20 (ну в идеале естественно 24).


Я имею в виду, сколько кадров в секунду ты можешь сжать без передачи, а то есть подозрение, что больше 8-ми. Проверь.


 
Nic2   (2004-09-24 16:17) [7]

<<а то есть подозрение, что больше 8-ми. Проверь>>
Сама передача, в плане поедания системных ресурсов не стоит ничего. Если в коде поменять:
Socket.PostIt(ms);
на
//Socket.PostIt(ms);
не изменится ничего.
Все ресурсы "хавает" <jpg.SaveToStream(ms);>. (причем что интересно, что jpg.SaveToFile("c:\..."); работает ничуть не медленнее, хотя по логике ведь дисковые операции...).

Спасибо всем кто отозвался.


 
Анонимщик ©   (2004-09-24 16:41) [8]

Было где-то непроверенное мною утверждение, что в дельфи неэффективная реализация jpeg"а, это нужно бы проверить. Есть интелловская какая-то библиотека, не помню как называется. Хорошо бы, если бы ты проверил и рассказал.


 
Анонимщик ©   (2004-09-24 16:43) [9]

А какой процент времени занимает код

DC := GetDC(0);
   BInfo.bmiHeader.biSize := sizeof(tagBITMAPINFOHEADER);
   BInfo.bmiHeader.biWidth := 1024;
   BInfo.bmiHeader.biHeight := 768;
   BInfo.bmiHeader.biPlanes := 1;
   BInfo.bmiHeader.biBitCount := 24;
   BInfo.bmiHeader.biCompression := BI_RGB;
   binfo.bmiHeader.biSizeImage:=0;
   ScrBitmap := TBitmap.Create();
   ScrBitmap.Handle := CreateDIBSection(Canvas.Handle, BInfo, DIB_RGB_COLORS, Scr, 0, 0);
   bitblt(ScrBitmap.Canvas.Handle,0,0,1024,768,DC,0,0,srccopy);
   ScrBitmap.ScanLine[1];

и какой - все остальное? Смотрел профайлером?


 
WondeRu ©   (2004-09-24 16:53) [10]

у кого-то я видел замечательный способ сжимания картинок с экрана: "видеокарта с ТВ-выходом + карта видео захвата = гонишь всю захваченную картинку по сети пакетами, сжатыми по Mpeg4"


 
Nic2   (2004-09-24 17:01) [11]

1). Уже и тут покопался: называется библиотека Intel JPEG Library входит в состав чего-то типа пакета для разработчиков Intel IPP (Intel® Integrated Performance Primitive) но она написана на С (а я если честно с С не дружу);
2). А какой смысл в проценте времени этого кода, если я опытным методом установил, что ресурсы пожирает jpg.SaveToStream(ms);, который в свою очередь использует DIBNeeded. Я пытался писать все как есть в коде, только вместо
jpg.SaveToStream(ms);
писал
jpg.DIBNeeded;
Эффект тот же - 8 кадров.

А если закомментировать  jpg.SaveToStream(ms);/jpg.DIBNeeded; то получается 33 кадра в секунду, бе вывода на экран и 30 с выводом.

Спасибо всем, кто отозвался.


 
Nic2   (2004-09-24 17:06) [12]

<<гонишь всю захваченную картинку по сети пакетами, сжатыми по Mpeg4>>
Честно говоря сомнительно, что упаковка в JPEG более ресурсоемкая, чем упаковка в mpeg4.
К тому же единственный найденный мой метод упаковки в jpeg (через модуль VFW,...и еще несколько названий не помню), у меня не заработал, справки я к нему не нашел, и нигде в нете не увидел ни примеров, ни хотя-бы людей, которые с ним работали. Короче с этим лажа...

Спасибо всем, кто отозвался.


 
Nic2   (2004-09-24 17:10) [13]

To:WondeRu
Сижу на Делфе6, zlib в нем нет. Ща поставлю 7 Делфу. О результатах напишу.


 
WondeRu ©   (2004-09-24 17:19) [14]

в Mpeg4 сжимать будет DirectShow... короче забудь способ с платой захвата видео - ерунда полная!

Новая бредовая идея: ставишь мультиплексор себе с монитором, а на ведомые компы видеокарты с ТВ-выходом, протягиваешь РК кабель от каждого компа! и наслаждаешься 25 кадрами в секунду! ;)


 
Nic2   (2004-09-24 17:43) [15]

А еще лучше-все компы к себе на стол перетянуть. Все видно, частота смены кадров 100Гц! Так еще и управлять ими можно!!!!!!!!!!!!!!! Красота....


 
Анонимщик ©   (2004-09-24 18:34) [16]

Нет, глупости это. Видимо, проблема в больших размерах (1024 на 768) и 24-ых битах. Конечно, можно уменьшить битность до 256 цветов, будет быстрее. Для начала нужно выяснить, какая у людей максимальная скорость сжатия jpeg"ом для таких картинок.

Что же касается C, то у интела можно взять уже откомпилированную библиотеку, сам язык знать необязательно.

Попробуй задать вопрос на http://www.compression.ru/forum/, а результаты доложи.


 
Анонимщик ©   (2004-09-24 19:07) [17]

А из чего ты вывел, что именно сохранение в поток жрет ресурсы? Ведь если ты его отключишь, то я за оптимизатор не ручаюсь, даже если он отключен.


 
Nic2   (2004-09-24 19:16) [18]

См. ответ №11 пункт 2.
Из хелпа:
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
TJPEGImage.JPEGNeeded

Creates a new TJPEGData object if the jpeg image only has a bitmap and a jpeg is needed.

procedure JPEGNeeded;

Description

Call JPEGNeeded to create a new jpeg data source when the jpeg image has thrown away the jpeg data and only has an internal bitmap. JPEGNeeded creates a new jpeg data source. The SaveToStream method uses JPEGNeeded.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


 
Sapersky   (2004-09-25 01:48) [19]

Может, попробовать чего попроще, например, перевод в grayscale (цветом можно пожертвовать) и RLE (взять хотя бы этот форум, большая часть экрана - один цвет, так что RLE должен хорошо сработать).
Или передавать различия между соседними кадрами - AVI/MPEG вроде это и делают?
Или ещё есть такая мысль - относительно сжатия текстур, которое есть в современных картах... они только разжимают аппаратно, или сжимать тоже могут? В DX SDK написано:

use IDirectDrawSurface7::Blt or IDirectDrawSurface7::BltFast to blit from the uncompressed surface to the compressed surface. DirectDraw does the compression for you.

но как он её does, аппаратно или программно - не уточняется. Надо пробовать...


 
_silver ©   (2004-09-25 14:38) [20]

Я делал подобное.
jpeg там не нужен.
В общих чертах:
1. хук на все сообщения связаные с перерисовкой экрана
2. определить координаты перерисованного участка
3. bitblt с него и отправляешь это куда надо
Скорость не хуже чем у RAdmin( кстати он также сделан)


 
PGM_X   (2004-09-25 23:04) [21]

Для информации: чтение из видеопамяти операция на порядки медленне чем запись (на многи картах меряется в 5-6 Мб/с, только GeForce может похвастать приличной скоростью. Так что на тех же ATI лимитирует не сжатие в JPEG, а банальная низкая скорость чтения из памяти. Как раз BitBlt с экрана и будет все тормозить.


 
_silver ©   (2004-09-26 12:07) [22]

2PGM_X
bitblt работает довольно быстро, а сжатие в jpeg довольно долгая процедура. Если не веришь проверь


 
DeadMeat ©   (2004-09-26 13:36) [23]

В любом случае сжатие добавляет нагрузку... Ведь все равно надо еще и bitblt делать. Так что ИМХО, вариант [20] оптимальнее...


 
DeadMeat ©   (2004-09-26 13:43) [24]

Как дополнение к [20] можно попробовать усложнить.
Орагнизовать перехват EndPaint (или как она там зовется). При ее вызове отсылать данные из полученного от нее DC... Тогда и не надо BitBlt вообще вызывать...

ЗЫЖ. Это только идея. Не проверенно....


 
PGM_X   (2004-09-27 00:16) [25]

2 _silver: bitblt работает довольно быстро, а сжатие в jpeg довольно долгая процедура. Если не веришь проверь

Любая видеоплата не GeForce и 1280 на 1024 на 32 бита из видеопамяти (!) в обычную и фраза "довольно быстро" не будет казаться правильной. Была конкретная задача и тормоз было именно чтение из памяти при помощи BitBlt. А кодирование в JPEG решается хорошим процессором и чем дальше тем легче :-).


 
Анонимщик ©   (2004-09-27 11:45) [26]

Еще раз говорю, посмотри на свой код - если ты отключишь сохранение в поток, то и операции с jpeg-сжатием теряют смысл, поэтому оптимизатор может просто проигнорировать эти команды. Ты должен действительно проверить, какие операции самые тяжелые. Вполне возможно, PGM_X совершенно прав.


 
_silver ©   (2004-09-27 12:37) [27]


> _silver ©   (25.09.04 14:38) [20]

Оптимальнее этого варианта не будет.


 
Nic2   (2004-09-27 15:19) [28]

<<Для информации: чтение из видеопамяти операция на порядки медленне чем запись (на многи картах меряется в 5-6 Мб/с, только GeForce может похвастать приличной скоростью. Так что на тех же ATI лимитирует не сжатие в JPEG, а банальная низкая скорость чтения из памяти. Как раз BitBlt с экрана и будет все тормозить.>>

Заинтересовало меня это, проверил:
У меня машина с Radeon 9000(не про)128М
Проверил у коллеги у нее GeForce FX5200(не ультра)128М

Процы - чистые Pentium(не Celeron-ы): у меня-2,4. У нее - 2,6.
Оперативки по 512.

У меня мать 845, у нее - 848

Результат:
у меня - (как уже писал-7-8 кадров)
у нее - 2-3

По скорости Радик похоже все же круче.
ЗЫ: Это все уже становится интересным...(аж похоже на тесты видях!!!!)


 
PGM_X   (2004-09-27 16:49) [29]

За все GeForce я вероятно поспешил, radeon тоже старый какой-то был. Конкретно у меня: GeForce MX400, Athlon 800, 1024х768х16 = 56 FPS.


 
PGM_X   (2004-09-27 16:50) [30]

Удалено модератором


 
PGM_X   (2004-09-27 16:50) [31]

Удалено модератором


 
PGM_X   (2004-09-27 16:52) [32]

И чего это его утроило?


 
Nic2   (2004-09-27 17:34) [33]

_silver ©   (25.09.04 14:38) [20]

Если не затруднит, хотя бы  в общих чертах объясните:
- как получить координаты изменившегося куска экрана;
- после передачи этого куска на др. машину, как мне слить(а точнее наложить) изменившийся кусок на старый битмам?

Заранее спасибо.


 
_silver ©   (2004-09-27 19:08) [34]

Nic2   (27.09.04 17:34) [33]
Копай исходники WinVNC.
Если не знаешь С могу привести пример на delphi.


 
_silver ©   (2004-09-27 19:19) [35]

1. хук(обязательно в dll) на
WH_CALLWNDPROC
WH_GETMESSAGE
WH_SYSMSGFILTER
далее определяешь какое сообщение пришло
Самое сложное с WM_PAINT
Если WM_PAINT - определяешь координаты с помощью GetRegionData() (не забывая о том что для одного WM_PAINT может изменяться несколько регионов)
далее bitblt
для остальных сообщений - GetWindowRect.
2. ну это совсем уж
Что тебе мешает передать сначала координаты, а потом сам изменившийся кусок?
А потом тотже bitblt.


 
Nic2   (2004-09-27 19:48) [36]

Ну со вторым ступил, согласен....
Спасибо, попробую.


 
Nic2   (2004-10-04 20:06) [37]

Сделал упаковку через ZLibEx. Передаваемые кадры получаются обрезанными сверху  процентов на 20-25 (ну не обрезанные, а вместо полезного изображения черный фон). Может кто сталкивался, в чем прикол?

Заранее спасибо.


 
_silver ©   (2004-10-14 17:41) [38]

Nic2   (04.10.04 20:06) [37]
Так чем тебе

> _silver ©   (27.09.04 19:19) [35][Ответить]

не подходит?


 
GROL   (2004-10-17 01:33) [39]


> _silver ©   (25.09.04 14:38) [20]
> Я делал подобное.

Ловилась всякиая Windows-анимация, ну, тип выезжающее или плавно появляющееся меню, или только конечный результат?


 
_silver ©   (2004-10-18 12:23) [40]

GROL   (17.10.04 1:33) [39]
Зависит от того какие сообщения перехватывать.
Я делал перехват всех сообщений связаных с перерисовкой экрана, в том числе и те которые связаны с перерисовкой выпадающих меню.
Могу привести полный список сообщений которые надо перехватывать.



Страницы: 1 2 вся ветка

Форум: "Media";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.033 c
11-1089131367
Андрей
2004-07-06 20:29
2005.02.06
Наследник KOLEditBox и метод OnPaint


1-1106317905
Zevs_a
2005-01-21 17:31
2005.02.06
Иерархические структуры


4-1103123547
grigory
2004-12-15 18:12
2005.02.06
Узнать запущен ли процесс?


1-1106518099
Sphinxx
2005-01-24 01:08
2005.02.06
Ошибка при вызове функции из DLL


6-1101209946
leonidus
2004-11-23 14:39
2005.02.06
Кто использует TIEDownload, работает ли он через прокси?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский