'BitmapEncoder is slow on surface GO3
We are developping a WPF app in C# that will run on a Surface Go 3 Windows tablet.
In one of our pages, we need to be able to take a picture with the intergrated webcam. We display a live view of the webcam, and on the press of a button, we take a picture.
Here is my issue: The live view has horrible frame rate (around 12-15 I would say). Sometimes, the camera even freezes and need to restart the app.
We currently use a library that polls the camera on a timer. One of the functions from that library uses a BitmapEncoder to transform the SoftwareBitmap into an encoded jpeg image as a byte array. I have added traces in that function with timestamps to see what is taking so much time:
private byte[] SoftwareBitmap2ByteArray(SoftwareBitmap img)
{
if (img == null)
return Array.Empty<byte>();
using (var stream = new Windows.Storage.Streams.InMemoryRandomAccessStream())
{
// Encode the raw data to something we can display in 'Image' control tag.
var d0 = DateTime.Now;
BitmapEncoder encoder = BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream).GetAwaiter().GetResult();
var d1 = DateTime.Now;
encoder.SetSoftwareBitmap(img);
//encoder.FlushAsync().GetAwaiter().GetResult();
var d2 = DateTime.Now;
var temp = encoder.FlushAsync().GetAwaiter();
var d3 = DateTime.Now;
temp.GetResult();
var d4 = DateTime.Now;
// Transform the stream into a byte array.
var res = Stream2ByteArray(stream.AsStream());
double ms0 = (d1 - d0).TotalMilliseconds;
double ms1 = (d2 - d1).TotalMilliseconds;
double ms2 = (d3 - d2).TotalMilliseconds;
double ms3 = (d4 - d3).TotalMilliseconds;
double ms4 = (DateTime.Now - d4).TotalMilliseconds;
return res;
}
}
The part that takes so much time is the temp.GetResult(); line. this one line alone takes ~40ms (pretty much 99% of the function's time), which is way too long.
On PC, everything is good, but on the Go 3 tablet, it takes too much time.
The conversion seems to be needed for multiple reasons:
The Image control is not able to display a SoftwareBitmap. It needs a Byte array or regular BitmapImage if I understand properly.Passing it a Software bitmap, the app does not crash, but the image just doesn't display
We manage DLSRs as well, and the different APIs return different outputs. Some level of conversion will have to be done at some point so that the library receives the same image type for all cameras.
Is there any way to make this faster? Is this a known limitation with these tablets? I have read complaints online that it is quite laggy... But we are only talking about showing a live view of a webcam here. A brand new tablet should be able to do that!
Thank you,
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
