Hiya!

I've been searching the board and the 'net without any "straight-to-the-point" answer on this subject. I want to take a snapshot of a window and encode it to JPEG, and this process has to be done as fast as possible. So my question is, what method is recommended? What encoder to use?

Thanks in advance.

Regards,
Seb
Posted on 2005-11-14 19:16:39 by Seb
Hi!

I didn't get any answer in my previous post where I asked about screenshotting methods, but anyway, I've got a task to snapshot a window each N minutes, encode it to JPEG (I'll be using Intel's library), save it to a temporary file and upload it to a FTP. Now, the question is, what's needed to do this? I'm thinking of a timer, but not quite sure since I'll also be using a thread to avoid lag (or if there is any other way to snapshot/encode/upload without any lag, please let me know). I'm not sure how to proceed regarding the thread - would I recreate the thread each time the timer is called, or is there any better way to do this? Any suggestions are welcome.

Thanks in advance.

Regards,
Seb
Posted on 2005-11-18 06:19:31 by Seb
I've already got the code sorted for the screenshot --> JPG part, I just need to repeat this process each N minutes and I need it to be fast/good enough to not produce any lag whatsoever. I also know what functions to use for the FTP stuff, but I just need some help in the "anti-lag" part or whatever you wonna call it. :)
Posted on 2005-11-18 06:58:45 by Seb
Personally I think you should recreate the thread everytime your timer is up...
Posted on 2005-11-18 07:03:49 by roticv

Personally I think you should recreate the thread everytime your timer is up...


OK. When the thread is finished, will it delete itself or do I need to call ExitThread/TerminateThread?
Posted on 2005-11-18 07:13:22 by Seb
Why don't create a thread once upon application initialization and use some kind of loop with Sleep inside the thread to do the work?
Posted on 2005-11-18 09:36:07 by arafel
Create thread at startup. Have the thread run a loop where it does WaitForMultipleObject on two objects. One is a "Ok, time to quite", the other "Ok, time to grab screenshot". Main app will trigger the grab-screenshot by WM_TIMER, and trigger the end-thread when it's time to shut down the app.

This allows the thread code to be very simple, allow you to change timing method with very little hassle, and allow you to start/stop the screenshot grabbing. Grabbing and JPEG encoding should be done entirely in this thread.

For FTP'ing, I would involve a third thread and a processing queue (basically a list of files to be uploaded, protected with CRITICAL_SECTION to avoid multithreading problems, and probably an EVENT object for efficient blocking waits when there's no items in the queue).
Posted on 2005-11-18 09:51:58 by f0dder

Create thread at startup. Have the thread run a loop where it does WaitForMultipleObject on two objects. One is a "Ok, time to quite", the other "Ok, time to grab screenshot". Main app will trigger the grab-screenshot by WM_TIMER, and trigger the end-thread when it's time to shut down the app.

This allows the thread code to be very simple, allow you to change timing method with very little hassle, and allow you to start/stop the screenshot grabbing. Grabbing and JPEG encoding should be done entirely in this thread.

For FTP'ing, I would involve a third thread and a processing queue (basically a list of files to be uploaded, protected with CRITICAL_SECTION to avoid multithreading problems, and probably an EVENT object for efficient blocking waits when there's no items in the queue).



Interesting. I'm afraid I've got no knowledge in WaitForMultipleObjects and threads in general, do you think there are any examples which demonstrates the use of them both? Or would it be possible for you to post some (psuedo) code example?

Thanks in advance.

Regards,
Seb
Posted on 2005-11-18 14:51:38 by Seb
Threads are really simlple: you just call CreateThread. Your ThreadProc, which is run in newly created thread should end with ExitThread instead of simple 'ret'. That's all.

Create Event objects with CreateEvent. Event are either signaled, ro non-signaled, so you can think of them like 1-bit flags (either "on" or "off). You can manually set or reset an event with SetEvent or ResetEvent. Thread Proc should be waiting for the event to become signaled. To do this you call WaitForSingleObject or WaitForMultipleObjects (which is a bit more complicated). The "wait*" function returns either when the specified time elapses, or when the specified object becomes signaled. These functions are universal - they can wait for more things - not only events. But in the case of waiting for an event - The wait function returns when the specified event is SET.

So the algorithm is:
1. Main thread: create event(s)
2. Main thread: create thread(s)
3. New thread: WaitForSingleObject/WaitForMultipleObjects - wait for events events
4. a) Main thread: set the event when the time is right (for example: when the app should capture the screen)
  b) New thread: the wait function returns, so do the job and (1) wait again, or (2) call ExitThread to terminate the thread

Remember that handles to threads and events must be closed with CloseHandle. Otherwise you're not "mr. Proper" and your app is leaking the system resources.

Closing a handle to an event invalidates that event object, so you can no longer wait for it.

But...

Closing a thread handle does not terminate the associated thread. To remove a thread object, you must terminate the thread, then close all handles to the thread.


So you can create the thread and immediately close its handle. The thread will work correctly with its handle closed.
Posted on 2005-11-18 23:55:06 by ti_mo_n
Thanks ti_mo_n. :) Your reply was very helpful. I'll let you know how it goes.

Regards,
Seb
Posted on 2005-11-20 21:39:23 by Seb
Hi again!

I've managed to get screenshotting and uploading working, both running in separate threads. But, I've got a question; currently I'm waiting for the screenshot thread to finish (WaitForSingleObject), and after that I'm creating the upload thread using the same thread handle variable, but I've been thinking about creating the upload thread inside the screenshot thread, right after the screenshot has been saved and do WaitForSingleObject() on it - is this safe, and will I gain any speed by doing this (basically, I'd like the screenshot & upload to be as fast as possible)?

Besides that, I've got a problem with the FTPing. The way it is now, I'm uploading screenshots to the following path on the FTP server:


/var/www/program/shots/<date>/<ip>/


The problem is that I can't figure out how to determine if the <date> and <ip> folder inside "shots" already exists, if they do, just step into them and upload the screenshots, and if not, create them, step into them and upload the screenshots. I've tried loads of stuff, but nothing seems to work. Any ideas?

Thanks,
Seb
Posted on 2005-11-29 11:38:25 by Seb
I would set up all three threads when the app starts, and have them block on events that signals them to do their work...
Posted on 2005-11-29 11:48:58 by f0dder

I would set up all three threads when the app starts, and have them block on events that signals them to do their work...



I'm afraid my event/thread knowledge is a bit too limited for such things, ie. I don't know how to do it. :)
Posted on 2005-11-29 12:03:34 by Seb
IMHO:
1) all this stuff can be done in a single thread.
2) creating threads in WM_TIMER handler is not very safe - you can easy create multiple instances of thread if somethinc goes wrong in thread's body (bad ftp connection speed, etc)
Posted on 2005-11-29 18:20:49 by Bohdan