[XAP / BETA] WP7 Screen recorder (Based on "The DllImport Project")

Search This thread

fiinix

Retired Recognized Developer
Oct 9, 2010
570
224
28
Stockholm
WP7 Screen recorder program


>Zomg, the Chinese could not program good fps...
>So i super optimized the **** code of theirs.

Application features

* Full-screen mode "F11"
* Presentation-mode background color chooser. (Useful in F11 mode)
* Great features on UI (The cn version suck'ed with UI)
* Chose what IP port WP7<>Server talk over
* See frames count' received
* Start/Stop server at any time to continue later -button
* More than 2.3 (old) 4 fps (stable fps)! Yay.


BETA Preview (Watch via Youtube for 720p; damn 4:3 ratio):

Cable free demo (works kind of well) (depends on wifi latency for FPS)

Randoms:
>My rage post about how they cant code: http://forum.xda-developers.com/showpost.php?p=14916356&postcount=75
>This is the result, many extra fps (more to come), yay.


- Server is always backwards compatibility -

Fixed-list

- (v0.2) WP-Client: More frames, less lagg.
- (v0.3) WP-Client: -^- and now a idle fps @ 5.1~ YEAH (my phone, inside app)
> Added more cross-device compatibility for dehydration hack (forgot native dll's, remembered today, so i fixed them too)
> CSharp___DllImport.Dehydrator.AllowMultitasking = true; (threw exception's, gone now ^)
 
Last edited:

fiinix

Retired Recognized Developer
Oct 9, 2010
570
224
28
Stockholm
Duration taken for 1 thread render: 21.295 sec
Duration taken for 2 thread render: 20.232 sec

Saves 1 sec total per 100 frames (according to yesterdays benchmark compared with today's new code)
>Going for the better =D

1 frame = 0,2023 sec (200 ms) (fully rendered)

>Stack where the most time is wasted
>Sending it back to server, need multi-thread there toooo ;)

Eh, not the server transmit
>4.586 sec for 100 frames (static frame) (way to fast)
>0,04586 sec for 1 frame (45,86 milliseconds)


105,4 ms goes to "Phone.Screen.GetCaptureBytes(out buffer);"

+ So thats:
* 202 ms (get & render pixels)
* 45 ms (send pixels)
- Total of: 246 ms
> Average of 4,065 fps

Code:
var t = new Phone.Timers.HiPerfTimer();
t.Start();
for (int i = 0; i < 100; i++)
{
    first = CaptureData();
}
t.Stop();

More soon; and a release very soon.
 
Last edited:

Flow WP7

Member
Mar 23, 2011
29
3
Duration taken for 1 thread render: 21.295 sec
Duration taken for 2 thread render: 20.232 sec

What exactly are you rendering? cant you send the data as defalte stream to the server and render there?

Also why 2 threads for this slow operation any way?

105,4 ms goes to "Phone.Screen.GetCaptureBytes(out buffer);"

+ So thats:
* 202 ms (get & render pixels)
* 45 ms (send pixels)
- Total of: 246 ms
> Average of 4,065 ms

Your goal should be 105,4 ms since thats the upper bound.

Call Phone.Screen.GetCaptureBytes(out buffer); in 1 thread and fill a ring buffer with the info 3 to X elements.

Use antother thread to get them from this buffer, and send them. should be 120 ms then.

If i get something really wrong, please let me know, if you need help with multi threading stuff let me know.

regards.
 

fiinix

Retired Recognized Developer
Oct 9, 2010
570
224
28
Stockholm
What exactly are you rendering? cant you send the data as defalte stream to the server and render there?

Also why 2 threads for this slow operation any way?



Your goal should be 105,4 ms since thats the upper bound.

Call Phone.Screen.GetCaptureBytes(out buffer); in 1 thread and fill a ring buffer with the info 3 to X elements.

Use antother thread to get them from this buffer, and send them. should be 120 ms then.

If i get something really wrong, please let me know, if you need help with multi threading stuff let me know.

regards.
New demo video up. (Works perfect without cable!)
__
Getting fps is very hard :p
Fun Fun Fun!

"Also why 2 threads for this slow operation any way?"
> More threads = faster done.
__

This is the multi-threaded render'er, that converts the "argb" so it can be compressed to "jpeg" (8kb img out):
Code:
Phone.Screen.GetCaptureBytes(out buffer);

captureWorker1T.RunWorkerAsync();

int bufferPos = 576000;
int i = 191999;

while (i < 383998) // thread 2 on "main loop thread"
{
    arr[++i] = (buffer[bufferPos++] | (buffer[bufferPos++] << 8)) | (buffer[bufferPos++] << 16);
    arr[++i] = (buffer[bufferPos++] | (buffer[bufferPos++] << 8)) | (buffer[bufferPos++] << 16);
    arr[++i] = (buffer[bufferPos++] | (buffer[bufferPos++] << 8)) | (buffer[bufferPos++] << 16);
    arr[++i] = (buffer[bufferPos++] | (buffer[bufferPos++] << 8)) | (buffer[bufferPos++] << 16);
    arr[++i] = (buffer[bufferPos++] | (buffer[bufferPos++] << 8)) | (buffer[bufferPos++] << 16);
    arr[++i] = (buffer[bufferPos++] | (buffer[bufferPos++] << 8)) | (buffer[bufferPos++] << 16);
    arr[++i] = (buffer[bufferPos++] | (buffer[bufferPos++] << 8)) | (buffer[bufferPos++] << 16);
    arr[++i] = (buffer[bufferPos++] | (buffer[bufferPos++] << 8)) | (buffer[bufferPos++] << 16);
    arr[++i] = (buffer[bufferPos++] | (buffer[bufferPos++] << 8)) | (buffer[bufferPos++] << 16);
    arr[++i] = (buffer[bufferPos++] | (buffer[bufferPos++] << 8)) | (buffer[bufferPos++] << 16);
    arr[++i] = (buffer[bufferPos++] | (buffer[bufferPos++] << 8)) | (buffer[bufferPos++] << 16);
    arr[++i] = (buffer[bufferPos++] | (buffer[bufferPos++] << 8)) | (buffer[bufferPos++] << 16);
}

captureWorker1E.WaitOne();

return bmp;
 

Flow WP7

Member
Mar 23, 2011
29
3
Ok then i would suggest, a 3 thread setup.

1 to get the bytes, and put it into a ring buffer, the next pull it from the buffer and convert it to jpeg and put it into another buffer, and the last for sending it.

I would check if it makes sence to split this converting into two threads since its a single core cpu, calculation intense operations arent optmiziable by parellism, so you only get 1 sec by doing so, but expected would be a reduction by 50% in ms.

On the other hand getting the bytes isn't cpu intense there is a lot of locking going on and process boundaries stuff, that the os has to schedule, this should be easily optimizable.

regrads
 
Last edited:
  • Like
Reactions: fiinix

fiinix

Retired Recognized Developer
Oct 9, 2010
570
224
28
Stockholm
Currently down to (dump):
0.213043212890625
0.206085205078125
0.207977294921875
0.2100830078125
0.208038330078125
0.214019775390625
0.208526611328125
0.20501708984375

~206-245 ms
40 ms down average, haha.

lol, even better (Thank lord DllImport!)
All threads (in thread scope before while(...)):
Phone.TaskHost.SetThreadPriority(Phone.TaskHost.ThreadPriority.Highest);

0.183013916015625
0.1810302734375
0.18402099609375
0.182037353515625
0.183013916015625
0.18402099609375
0.1829833984375
0.19000244140625
 
Last edited:

Marvin_S

Retired Recognized Developer
Dec 8, 2010
883
239
Hey in my PM i ment this technique... dont know if it will help you out.

The Image (800*480):
Line 0 ................ (480px)
Line 1 ................ (480px)
Line 2 ................ (480px)
Line 3 ................ (480px)
[...]
Line 800.............. (480px)

render 1 will register all EVEN lines only and send it to the server as an image of 480*400,
render 2 will render all ODD lines of the next frame and send it to the server,
render 3 will render all EVEN lines of frame 3 and send it
render 4 will render all ODD lines of frame 4, etc. etc.

Then the server will restore these images:
frame 1 (480*800): render 1 (400 even lines) + render 2 (400 odd lines),
frame 2 (480*800): render 3 (even) + render 2 (odd),
frame 3 (480*800): render 3 (even) + render 4 (odd),
frame 4 (480*800): render 5 (even) + render 4 (odd),

So you will get the equal amount of frames as renders but the only difference your renders are half the size (480*400).

if you can get a decent framerate, this trick might result into an even higher FPS. The downside if the framerate is not high enough you might notice "scanlines". Idk if it is worth the try or worth implementing as some people might prefer higher framerate over better quality.

if needed you can ofcourse use 2 threads as well to process 200 lines per thread.
 
Last edited:

fiinix

Retired Recognized Developer
Oct 9, 2010
570
224
28
Stockholm
The problem is in C++, its to slow.
200ms~ is the absolute lowest we can go.
We need more advanced c++ like ddraw (Direct Draw).
The C# is so optimized that its almost not even possible to go lower because it depends on C++ code behind.
Ill look in to some ddraw code.

Average: 200ms:
Code:
var t = new Phone.Timers.HiPerfTimer();
t.Start();
for (int i = 0; i < 200; i++)
{
    first = CaptureData();
}
t.Stop();
 

phil_rouge

Senior Member
Dec 9, 2007
173
2
56
Nice
www.pilou.com.fr
Thank's for this great application !

I have one question : I run WP7 Screen Recx- Server on my PC, apps on my mozart, I put Server IP and clic Start, ok now I have my screen on PC but if I clic on Home or another key on my Mozart I dont have image on PC only the screen with server IP, server Port ...
How can I make to use with Zune, Camera or another apps ?

:confused:
 

Top Liked Posts

  • There are no posts matching your filters.
  • 14
    WP7 Screen recorder program


    >Zomg, the Chinese could not program good fps...
    >So i super optimized the **** code of theirs.

    Application features

    * Full-screen mode "F11"
    * Presentation-mode background color chooser. (Useful in F11 mode)
    * Great features on UI (The cn version suck'ed with UI)
    * Chose what IP port WP7<>Server talk over
    * See frames count' received
    * Start/Stop server at any time to continue later -button
    * More than 2.3 (old) 4 fps (stable fps)! Yay.


    BETA Preview (Watch via Youtube for 720p; damn 4:3 ratio):

    Cable free demo (works kind of well) (depends on wifi latency for FPS)

    Randoms:
    >My rage post about how they cant code: http://forum.xda-developers.com/showpost.php?p=14916356&postcount=75
    >This is the result, many extra fps (more to come), yay.


    - Server is always backwards compatibility -

    Fixed-list

    - (v0.2) WP-Client: More frames, less lagg.
    - (v0.3) WP-Client: -^- and now a idle fps @ 5.1~ YEAH (my phone, inside app)
    > Added more cross-device compatibility for dehydration hack (forgot native dll's, remembered today, so i fixed them too)
    > CSharp___DllImport.Dehydrator.AllowMultitasking = true; (threw exception's, gone now ^)
    1
    This will work with games ?
    It captures frames globally on the phone, wherever you are; games, yes, but the wifi limitations etc holds the fps down. Later i will take milliseconds benchmark to see where all the functions are un-optimized.
    1
    Ok then i would suggest, a 3 thread setup.

    1 to get the bytes, and put it into a ring buffer, the next pull it from the buffer and convert it to jpeg and put it into another buffer, and the last for sending it.

    I would check if it makes sence to split this converting into two threads since its a single core cpu, calculation intense operations arent optmiziable by parellism, so you only get 1 sec by doing so, but expected would be a reduction by 50% in ms.

    On the other hand getting the bytes isn't cpu intense there is a lot of locking going on and process boundaries stuff, that the os has to schedule, this should be easily optimizable.

    regrads
    1
    it is just a greal tool...

    i just wrote an post on our german WP7 Blog -> http://sevenhub.de/wp7/news/wp7-screen-recorder-phone-7-am-pc-monitor/
    1
    Would it be possible to get this working on Mango?

    Yes and no. Look up "WP7 Root Tools" on this forum; it should be able to enable running apps like this one on Mango.

    However, running any app with COM interop, including both WP7 Root Tools and this app, is blocked by default on Mango. To unblock, you need "interop-unlock" which is dev-unlock plus changing a registry value. However, this typically requires that you first be on pre-Mango. If you actually have a HTC Titan (HOW?!?) that may not be possible for you.

    On the other hand, the community will definitley keep working on the problem.

    EDIT: It should be totally possible to make an app like this one work on Mango. It'll require some tweaks to make it Mango compatible, but on the other hand it should be possible to do it without actually needing ID_CAP_INTEROPSERVICES (the pre-Mango version needed that to enable multitasking, but I think you can just use the new Mango multitasking APIs to make this work).