Big performance difference between WinForms and Wpf examples - cefsharp

I notice a very important performance difference (in FPS) between the CefSharp.WinForms.Example and CefSharp.Wpf.Example when using http://www.vsynctester.com
When turning off VSync in my video card control panel and in the settings in CefExample Init()
settings.CefCommandLineArgs.Add("disable-gpu-vsync", "0");
For CefSharp.WinForms.Example I get around 500 FPS (steady)
For CefSharp.Wpf.Example I barely get 30 FPS
I understand that Wpf uses offscreen rendering, but what explains the big performance difference for the same web page?
I'm using a MacBook Pro with Win 8.1 with NVidia GT 750M Graphics.
CefSharp version is 8755a9496ffbd5f21bc6ef062bce687a22d83938 (March 1st 2015) and Cef version 3.2171.1979

The maximum rate in frames per second (fps) that CefRenderHandler::OnPaint will be called for a windowless browser. The actual fps may be lower if the browser cannot generate frames at the requested rate. The minimum value is 1 and the maximum value is 60 (default 30).
Direct quote from the CEF documentation see http://magpcss.org/ceforum/apidocs3/projects/%28default%29/_cef_browser_settings_t.html#windowless_frame_rate
The entire process is more CPU bound that it is GPU bound. The slow part is the bitmap buffer is copied in memory, before it's displayed. CEF also supports DirtyRects which is currently not implemented, so even a small graphical change forces a complete screen redraw.
When the upstream CEF issue 1006 is resolved we can then look at making some more improvements.
https://code.google.com/p/chromiumembedded/issues/detail?id=1006&q=label%3AOSR

Related

How to synchronize QAudioOutput on multiple devices?

I have an audio playing app that runs on several distributed devices, each with their own clock. I am using QAudioOutput to play the same audio on each device, and UDP broadcast from a master device to synchronize the other devices, so far so good.
However, I am having a hard time getting an accurate picture of "what is playing now" from QAudioOutput. I am using the QAudioOutput bufferSize() and bytesFree() to estimate what audio frame is currently being fed to the sound system, but the bytesFree() value progresses in a "chunky" fashion, so that (bufferSize() - bytesFree()) / bytesPerFrame doesn't give the number of frames remaining in the buffer, but some smaller number that bounces around relative to it.
The result I am getting now is that when my "drift indicator" updates, it will run around 0 for several seconds, then get indications in the -15 to -35 ms range every few seconds for maybe 20 seconds, then a correcting jump of about +120ms. Although I could try to analyze this long term pattern and tease out the true drift rate (maybe a couple of milliseconds per minute), I'd much rather work with more direct information if it's available.
Is there any way to read the true number of frames remaining in the QAudioOutput buffer while it is playing a stream?
I realize I could minimize my problems by radically reducing the buffer size and feeding QAudioOutput with a high priority process, but I'd rather have a solution that uses longer buffers and isn't so fussy about what it runs on - target platforms vary from Windows 10 machines to Raspberry Pi Zero Ws, possibly to Android phones.

Maptiler Pro Demo 12 Core using only 12%

Using MapTiler Pro Demo. Testing zoom levels 1-21 for Google Maps export from a tiff image (about 21mb file covering polygons over 2000km).
At the moment its been running an hour with constant usage at 12% of 12 vcores (about 1.5 of 12) maxed to about 2.5ghz. No tiles has been exported yet, only the html's associated.
Am I too quick to judge performance?
Edit: Progressbar at 0%
Edit2: Hour 8 still 0%. Memory usage increased from 400mb to 2gb
You are trying to generate from your input 21 MBytes file about 350 GBytes of tiles (approx. 10 billion of map tiles at zoom level 21) by the options you have set in the software. Is this really what you want to do?
It sounds like a nonsense to render the very low-res image (2600 x 2000 pixel) covering a large area (such as the South Africa) down to zoom level 21!
The software has suggested you the default maxzoom 6. If your data are coverage maps or similar dataset it makes sense to render it maybe down to zoom level 12 or similar, definitely not deeper than 14. For standard input data (aerial photo) the native suggested maxzoom +1 or +2 is the max which really makes sense. Deeper zoom levels do not add any visual advantage.
The user can always zoom deeper - but the upper tiles can be displayed on the client side - so you don't really need to generate and save all these images at all...
MapTiler automatically provides you with a Google Maps V3 viewer, which is doing the client-side over zooming out of the box.
See a preview here:
http://tileserver.maptiler.com/#weather/gmapsmaptiler.embed
If you are interested in the math behind the map tiles, check:
http://tools.geofabrik.de/calc/#type=geofabrik_standard&bbox=16.44,-34.85,32.82,-22.16
Thanks for providing the report (with http://www.maptiler.com/how-to/submit-report/) to us. Your original email to our support did not contain any technical data at all (not even the data you write here on the stackoverflow).
Please, before you publicly rant on the performance of a software - double check you know what you do. MapTiler Pro is a powerful tool, but the user must know what he does.
Based on your feedback - we have decided to implement for a future version of the MapTiler software an estimated final output size - and warn the user in the graphical user interface if he chooses options which are probably unwanted.

Preview issues for 1080P video using DirectShow

I am using DirectShow in my application to capture video from webcams. I have issues while using cameras to preview and capture 1080P videos. Eg: HD Pro Webcam C910 camera of Logitech.
1080P video preview was very jerky and no HD clarity was observed. I could see that the enumerated device name was "USB Video Device"
Today we installed Logitech webcam software on these XP machines . In that application, we could see the 1080P video without any jerking. Also we recorded 1080P video in the Logitech application and saw them in high quality.
But when I test my application,
I can see that the enumerated device name has been changed to "Logitech Pro Webcam C910" instead of the "USB Video Device" as in the previous case.
The CPU eaten up by my application is 20%, but the process "SYSTEM" eats up 60%+ and the overall CPU revolves around 100%
Even though the video quality has been greatly improved, the jerks are still there, may be due to the 100% CPU.
When I closed my application, the high CPU utlizaton by "System" process goes away.
Regarding my application - It uses ICaptureGraphBuilder2::RenderStream to create Preview and Capture streams.
In Capture Stream, I connect Camera filter to NULL renderer with sample grabber as the intermediate filter.
In preview stream, I have
g_pBuild->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,cam,NULL,NULL);
Preview is displayed on a windows as specified using IVideoWindow interface. I use the following
g_vidWin->put_Owner((OAHWND)(HWND)hWnd);
g_vidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
g_vidWin->put_MessageDrain((OAHWND)hWnd);
I tried setting Frame rate to different values ( AvgTimePerFrame = 500000 ( 20 fps ) and 666667(15 fps) etc.
But all the trials, still give the same result. Clarity has become more, but some jerks still remain and CPU is almost 100% due to 60+ % utlilization by "System". When I close my video application, usage by "System" goes back to 1-2 %.
Any help on this is most welcome.
Thanks in advance,
Use IAMStreamConfig.SetFormat() to select the frame rate, dimensions, color space, and compression of the output streams (Capture and Preview) from a capture device.
Aside: The comment above of "It doesn't change the source filter's own rate" is completely wrong. The whole purpose of this interface is to define the output format and framerate of the captured video.
Use IAMStreamConfig.GetStreamCaps() to determine what frames rates, dimensions, color spaces, and compression formats are available. Most cameras provide a number different formats.
It sounds like the fundamental issue you're facing is that USB bandwidth (at least prior to USB3) can't sustain 30fps 1080P without compression. I'm most familiar with the Microsoft LifeCam Studio family of USB cameras, and these devices perform hardware compression to send the video over the wire, and then eat up a substantial fraction of your CPU on the receiving end converting the compressed video from Motion JPEG into a YUV format. Presumably the Logitech cameras work in a similar fashion.
The framerate that cameras produce is influenced by the additional workload of performing auto-focus, auto-color correction, and auto-exposure in software. Try disabling all these features on your camera if possible. In the era of Skype, camera software and hardware has become less attentive to maintaining a high framerate in favor of better image quality.
The DirectShow timing model for capture continues to work even if the camera can't produce frames at the requested rate as long as the camera indicates that frames are missing. It does this using "dropped frame" count field which rides along with each captured frame. The sum of the dropped frames plus the "real" frames must equal the requested frame rate set via IAMStreamConfig.SetFormat().
Using the LifeCam Studio on an I7 I have captured at 30fps 720p with preview, compressed to H.264 and written an .mp4 file to disk using around 30% of the CPU, but only if all the auto-focus/color/exposure settings on the camera are disabled.

How to Save an Image of a Large Flex Component (EX: 25000px by 3000px # 72dpi)

My application consists of displaying a large custom tree like structure to the user that can eventually grow to massive proportions like the dimensions listed in the question. I allow them to export the image with the following line of code tied to a button click event:
var image:ImageSnapshot = ImageSnapshot.captureImage(this, 72, new PNGEncoder(), false);
I've managed to export images close to the dimensions listed but around there it start to get the error message listed below after spinning for close to 15 seconds:
Error: Error #1000: The system is out of memory.
at flash.utils::ByteArray/writeBytes()
at mx.graphics::ImageSnapshot$/mergePixelRows()[E:\dev\4.x\frameworks\projects\framework\src\mx\graphics\ImageSnapshot.as:511]
at mx.graphics::ImageSnapshot$/captureAll()[E:\dev\4.x\frameworks\projects\framework\src\mx\graphics\ImageSnapshot.as:482]
at mx.graphics::ImageSnapshot$/captureImage()[E:\dev\4.x\frameworks\projects\framework\src\mx\graphics\ImageSnapshot.as:318]
at vertical/saveChart()[C:\devel\workspace\vertical\src\CustomObject.mxml:501]
at vertical/__saveImageBtn_click()[C:\devel\workspace\vertical\src\CustomObject.mxml:574]
Is the flashplayer plugin for my browser running out of memory? I noticed in my task manager it got up to about 1.2GB of memory usage(I have 4GB on my system). If that is the case is it possible to limit the memory usage for a given function like the ImageSnapshot.captureImage() call above?
Is there maybe a way to generate the component into 2 or 4 ImageSnapshot objects and piece them together afterward?
Any advice would be greatly appreciated.
I believe the latest Flash Player 11 has a new feature to solve this issue:
"Enhanced high resolution bitmap support — BitmapData objects are no longer limited to a maximum resolution of 16 megapixels (16,777,215 pixels), and maximum bitmap width/height is no longer limited to 8,191 pixels, enabling the development of apps that utilize very large bitmaps." from this PDF
If you are using BitmapData, it makes a difference which FlashPlayer you are targetting:
versions VS maximum bitmapsize
flashplayer -9 : 2880x2880 px
flashplayer 10 : 4096x4096 px
flashplayer 11 : unlimited
I don't know what you exactly are trying to do with this huge capture, but I would recommend using tiles. Break it down to chunks of relative small bitmaps. Create them separately, so you don't have to open/create that huge amount of data in your memory.
Anyway, it would be nice to know if it is possible to encode that big-ass sized image, without Error #1000 out of memory errors.

Environment.WorkingSet incorrectly reports memory usage

Environment.WorkingSet incorrectly reports the memory usage for a web site that runs on Windows 2003 Server.(OS Vers: Microsoft Windows NT 5.2.3790 Service Pack 2, .NET Vers: 2.0.50727.3607)
It reports memory as Working Set(Physical Mem.): 1952 MB (2047468061).
Same web site runs locally on Windows Vista with a Working Set(Physical Mem.): 49 MB (51924992).
I have limited access to the server and support is so limited :(.
so i have computed the total memory by traversing with VirtualQuery.
Total of pages with state: MEM_FREE is 1300 MB.
(I guess server have 4 GBs of RAM and PAE is not enabled, max user mode virtual address is 0x7fff0000.)
So, i know working set is not only about virtual memory. But, is it normal to have such a high working set while its very low on another machine?
I think the problem is related to what is described in this article:
MAY 04, 2005
Fun with the WorkingSet and int32
I finally found an honest to goodness bug in the .NET framework.
... the
WorkingSet returns the amount of memory being used by the process as
an integer (32 bit signed integer). OK, so the maximum value of an
integer is 2,147,483,647 -- which is remarkably close to the total
amount of memory that a process can have in its working set.
... There is actually a switch in Windows that will allow a process to use
3 gig of memory instead of 2 gig. This switch is often turned on when
dealing with Analysis Services -- this thing can be a memory hog. So
now what happens is that when I poll the WorkingSet I get a negative
number, a really big negative number. Usually, in the realm of
-2,147,482,342.
... The problem was the overflow bit.
Working set is returned to the .NET framework as a binary value. The
first bit of an integer is the sign bit. 0 is positive, 1 is negative.
So, when the value turned from (binary)
1111111111111111111111111111111 to (binary)
10000000000000000000000000000000 the value goes from 2147483647 to
-2147483647.
OK, so I still have to fix this. Here is what I came up with (in C#):
long lWorkingSet = 0;
if (process.WorkingSet >= 0)
lWorkingSet = processWorkingSet;
else
lWorkingSet = ((long)int.MaxValue*2)+process.WorkingSet;
Hopefully that fixes the problem for now.
The real question will come in down the road. Microsoft knows about
this problem. I still have find out how they are going to fix this for
Win64...where this trick will no longer work.
http://msdn2.microsoft.com/library/0aayt1d0(en-us,vs.80).aspx:
There's gonna be a Process.WorkingSet64 variable, and they're
deprecating WorkingSet.
On a tangent, though, I thought it was impossible for a managed
process to come near the 3gb limit, because the runtime splits the
memory into multiple heaps. Is this not true?
At a guess, Environment.WorkingSet is probably returning the value from GetProcessWorkingSetSize, which is basically what has been set with SetProcessWorkingSetSize. It's basically whatever the system has picked as the largest working set size it would like to see for this process, not necessarily anything to do with how much memory it's actually using. The basic effect is that when/if the process uses more memory than that, the system's working set trimmer goes to work seeing if it can get some of its memory paged out to disk.

Resources