Hi,
I am trying to implement a Win32 screen capture application similar to VNC.
The issue is, the Bit blt function call that i am using to capture the screen chokes up the cpu when the hardware acceleration is FULL. The Cpu goes upto 100% and stays there.
I tried BItBlt on the HDC obtained from CreateDIBSection and CreateCompatibleBitmap funtions, but both gave the same result.
When i set the Hardware acceleration to NONE the cpu utilisation is atmost 30%.
Is there any way that i can reduce the BitBlt CPU usage when hardware accleration is set to FULL.
How disabled hardware acceleration with API?
Please help.
Thanks,
you didn't show us any code
but, i can guess what the problem is
you handle the WM_PAINT message without validating the update region
it will continually send WM_PAINT messages until the region is updated
one way to avoid this is to call BeginPaint and EndPaint
another way is to exit WndProc via DefWindowProc for WM_PAINT messages
still another way would be to call ValidateRect
Correct, I handle to message "WM_PAINT". Attached code Hook.
When detect "WM_PAINT", sent a message for capturing screen.
Please could you explain with my example?
Thank you very much
i don't know what you're tring to do, there :P
but, give me a few minutes, and i will post a simple example using WM_PAINT, BeginPaint, EndPaint
see attached...
Hi Dave,
good catch. :t I hope it'll help our friend.
Gunther
I not very clear understand you code, but by concepts could remark - BitBlt algo making few MFLOPS processing all pixels, so easy could overload processor. For avoiding it is need to split algo on more smaller parts, that's running in threads, meanwhile main thread calling Yield function waiting results - so, you need to manually rewrite you version of BitBlt (suppose even part of it), and support this processing big (attended to time when original code was written) resolution of modern screens.
AFAIK, WM_PANIT sometime called hundreds time a seconds and that is why it make your CPU usage goes to 100%. I used to limited the Bitblt to 60 FPS, and bitblt is very efficient compared than creating your own using the CPU. Bitblt is hardware accelerated, even on my old zyrex EGT there is only bitblt which is hardware accelerated, and OpenGL used it too to create the texture maping.
Thank to All,
Sorry my english is very bad.
I capture the screen in several frames, but the cpu performance is up 100%. I divide the screen into columns and rows.
I thinks as Farabi says: "WM_PANIT sometime called hundreds time a seconds "
Farabi, how limit "BitBLt" to 60 FPS?
Is best to use timer in lieu of a hook?
multimedia timers are a bit more complicated, but provide higher resolution
the standard windows timer has a resolution of either 10 or 16 mS, depending on the system
if you want exactly 60 FPS, you'll have to use the multimedia timer resolution of 1 mS and fudge
The timeBeginPeriod (http://msdn.microsoft.com/en-us/library/windows/desktop/dd757624(v=vs.85).aspx) function sets the minimum resolution for all of the periodic timers, not just the multimedia timers. But if CPU usage is a problem, setting a higher resolution for the periodic timers will likely make the problem worse.
To limit the frequency of an event, you could poll a suitable timer in your message loop. QueryPerformanceCounter (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx) is one possibility.
If your WM_PAINT message is coming too often, it's a design problem.
Anyways, check pDueTime in SetWaitableTimer (http://msdn.microsoft.com/en-us/library/windows/desktop/ms686289%28v=vs.85%29.aspx).
You could give a example to " SetWaitableTimer"?
Please, thank you very much.
You could give a example to " QueryPerformanceCounter"?
Please, thank you very much.
Quote from: AsmAlmeria12 on April 24, 2014, 03:09:17 AM
You could give a example to " SetWaitableTimer"?
Try this. (https://www.google.com/search?q=SetWaitableTimer+example)
BTW, in your hook code I see
.elseif [edx].message == WM_KEYDOWN
invoke PostMessage, HWND_BROADCAST, HwdMensaje,0,0
... shouldn't that be
invoke PostMessage, HWND_BROADCAST, HwdMensaje,wParam,lParam
??? You want to know
which key was pressed, right?
Why is HWND_BROADCAST used? This produce useless message processing in all GUI threads except the thread of the actual target window.
For WM_PAINT I would pool the paint requests over a specific time interval and then copy the corresponding screen region.
Hi, good night from southern Spain.
My program used the hook for see if there change of the screen. If there change ("WM_PAINT" , "WM_KEYDOWN" And "WM_MOUSEMOVE"), sent a message for capture to the all screen.
I use "HWND_BROADCAST " . Fails to reach the message specifying the handler my thread. I've tried "invoke PostMessage, HwndMyThread, HwdMensaje,0,0" but doesn't work.
My hook is only a jumper for capture to the screen.
Farabi, MichaelW and Qword, tell me limit the frequency of an event ("WM_PAINT", "WM_KEYDOWN" Y "WM_MOUSEMOVE"), for reducing the use CPU. I dont know how limit the frequency??.
Another example, please?
Other way, please?
Can you please give us some more details about your intention? Why do you need to write a program for remote control in Assembler?
Edit: Finished the example :lol:
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
.data
pc_frequency dq 0
pc_count dq 0
r8 REAL8 ?
hTimer HANDLE 0
msg MSG <>
.code
;==============================================================================
TimerProc proc hwnd:HWND, uMsg:UINT, idEvent:DWORD, dwTime:DWORD
;---------------------------------------------------
; On the first call initialize pc_count and return.
;---------------------------------------------------
mov eax, DWORD PTR pc_count
or eax, DWORD PTR pc_count+4
jnz @F
invoke QueryPerformanceCounter, ADDR pc_count
ret
@@:
;---------------------------------------------------------------
; Calc and display the elapsed seconds since the previous call.
;---------------------------------------------------------------
fild pc_count
invoke QueryPerformanceCounter, ADDR pc_count
fild pc_count
fsubr
fild pc_frequency
fdiv
fstp r8
printf("%f\n", r8)
ret
TimerProc endp
;==============================================================================
start:
;==============================================================================
invoke QueryPerformanceFrequency, ADDR pc_frequency
printf("%I64d\n", pc_frequency)
invoke SetTimer, 0, 0, 1000, ADDR TimerProc
push eax
;-------------------------------------------------
; For this type of timer to work in a console app
; the calling thread must dispatch messages.
;-------------------------------------------------
@@:
invoke GetMessage, ADDR msg, NULL, 0, 0
invoke DispatchMessage, ADDR msg
invoke GetAsyncKeyState, VK_ESCAPE
test eax, 1
jz @B
pop eax
invoke KillTimer, 0, eax
inkey "Press any key to exit..."
exit
;==============================================================================
end start
3579545
1.001420
1.001432
1.001438
1.001461
1.001426
1.001437
1.001436
1.001504
1.001374
1.001440
1.001449
1.001435
1.001436
1.001443
QuoteMy program used the hook for see if there change of the screen. If there change ("WM_PAINT" , "WM_KEYDOWN" And "WM_MOUSEMOVE"), sent a message for capture to the all screen.
Why do you need to capture every change in the screen?
Yes, my intention is to create a program to view multiple PCs remotely.
Attached Demo.
Config.INI:
ip=192.168.1.197 (Ip Server)
puerto=8889 (Port)
tipocursor=0 (1 = BitBlt with CAPTUREBLT Or SRCCOPY. 0 = BitBlt only SRCCOPY)
modo=1 (1 = Server. 0 = Client)
coldivpantalla=1 (Columns split screen)
fildivpantalla=1 (Rows split screen)
tipoenvio=1 (Send)
tipoimg = 0 (0 = type image JPG. 1 = type image BMP)
The program still did not work well. Is a prototype.
Is only for 32bits.
On some computers the CPU is high.
The program only send images, when GPS.DLL (hook) see a change.
MichaelW, thanks for the example, I now understand the function "QueryPerformanceFrequency"
Hi,
This is correct, for calculate the time (miliseconds) it takes my function in screen capture?
Code:
.Data
pc_frequency DQ 0
IniTime DQ 0
FinTime DQ 0
.Code
.
.
Invoke QueryPerformanceFrequency, Addr pc_frequency
Invoke QueryPerformanceCounter, Addr IniTime
Invoke CaptureScreen ; Function capture the screen.
Invoke QueryPerformanceCounter, Addr FinTime
Xor Edx, Edx
Mov Eax, DWord Ptr FinTime
Mov Ebx, DWord Ptr IniTime
Sub Eax, Ebx
Mov Ebx, 1000
Mul Ebx
Mov Ebx, DWord Ptr pc_frequency
Div Ebx
.
.
.
;calculate performance counter counts per millisecond
;this only needs to be done once, at program initialization
;the result may then replace the low dword of pc_frequency
mov eax,dword ptr pc_frequency
mov edx,dword ptr pc_frequency[4]
mov ecx,1000
div ecx
;round to nearest
shr ecx,1
cmp edx,ecx
sbb eax,-1
mov dword ptr pc_frequency,eax
;then, to calculate elapsed time...
mov eax,dword ptr FinTime
mov edx,dword ptr FinTime[4]
mov ecx,dword ptr pc_frequency
sub eax,dword ptr IniTime
sbb edx,dword ptr IniTime[4]
div ecx
;round to nearest
shl edx,1
cmp edx,ecx
sbb eax,-1
I think you can use the Bitblt calling on separate thread, and then set the thread to run each 100ms by set the thread execution delay using Sleep function.
Hi all,
Attached a example, for screen capture.
Screen capture at 25 FPS.
I capture the screen using BitBlt and GetDiBits for save bits and then send. I do not know if I can use only GetDibits for capture the bits. You know if you can?
I'm desperate!. Thanks in advance
Hi all,
I'm debugging my program, I have seen, a problem in my send by socket.
I use socket Async, I use the function "WSAAsyncSelect" for know when to send packet.
What type of socket should I use me?, socket type of blocking or not?
Thanks is advance!.
Hi all,
The performance problem is in the size of image.
Anyone have any example to zlib version 1.2.8?, for function "compress".
I tried "zlibstat.lib and zlibstat.inc" but gives error: "zlibstat.lib(crc32.obj) : fatal error LNK1103: debugging information corrupt; recompile module"
If anyone has ".Lib and .Inc" would greatly appreciate it.
Thank you very much.
use the forum search tool for "zlib"
i seem to recall someone playing with that a while back
Hi Debndave,
In the forum mams32, I have seen some examples and I have also read your manual and faq to zlib.
But I can not make it work, the function "compress/uncompress"
I have the following error:
"fatal error LNK1103: debugging information corrupt; recompile module"
You could help me?.
you would have some example for masm32? Or zlib.lib and zlib.inc for masm32?.
Thank is advance.
This might be something that will help you: http://www.masmforum.com/board/index.php?topic=9039.0
Ive attached zlibstat.inc and zlibstat.lib (which is zlib v1.1.4) unfortunately i havent been able to find a newer version of the static library or compile it from the various sources online - always get issues with unresolved externals and name decoration issues (even using vortex's undecor tool). Maybe someone else can take a stab at compiling a static zlib library that can be linked with assembler projects. Anyhow v1.1.4 works mostly, and this is the version i used for the zlibextract lib i created as well, which can be found in the following thread http://masm32.com/board/index.php?topic=421.0
Thank fearless :eusa_clap: :eusa_clap:
This lib and inc, if well.
Thank you very much.
As you found - problem in size of image, so compressing only will add MFLOPS to you thread - what will be in such case you could test on GER program example (MT) from my site packing any data over 5 GB. The reason is simple - threads in my archiver make each time more then 1 MFLOPS per thread. So could work only on machive with plants cooling, and even for me modify packing algo that will fit to limit is quite difficult.
Hi Adamanteus,
Debugging my program, I have seen several errors:
1 Compressing and size the image.
If the packet too large to send, the "socket", overload the processor and network.
2 Like you said in your previous post, "BitBlt algo making few MFLOPS processing all pixels, so easy could overload processor".
I tried to changed the image size with function "StretchBlt" and colour, the performance is better.
I managed to reduce the use CPU from 100% to 30%.
But I see another program like "Teamviewer" that the use to CPU is 5%. How is does?.
My program is ready for divide the screen in columns and rows. But the result does not vary much.
I need advices.
i don't think TeamViewer supports 25 FPS :P
I think if you could scale down the image with the function "StretchBlt" and send it.
And when on the other side is received, the image is enlarged, and pixel-level retouching for to view it.
This may be correct?
The first part, this clear. the dificult is the second part.
Understand what I like to do?. (my english is very bad).
Any tips?
Thank you very much.
BitBlt will normally be a little faster than StretchBlt
either way, you end up with a DIB
you could shrink it considerably by converting it to a JPG or PNG
perhaps even moreso if you converted it to 256 colors and made a GIF