我正在写一些使用SkiaSharp渲染相机预览的代码。这是跨平台的,但我在为android编写实现时遇到了一个问题。
我需要将YUV_420_888转换为RGB8888,因为这是SkiaSharp所支持的,并且在this thread的帮助下,以某种方式设法在我的SkiaSharp画布上显示了相当高质量的图像。问题出在速度上。在最好的情况下,我可以得到大约8fps,但通常只有4到5fps。事实证明,最大的因素是转换。我现在有大约3个版本的ToRGB转换器。我甚至尝试过“不安全”代码和并行循环。我会给你看我最好的一张。
private unsafe byte[] ToRgb(byte[] yValuesArr, byte[] uValuesArr,
byte[] vValuesArr, int uvPixelStride, int uvRowStride)
{
var width = PixelSize.Width;
var height = PixelSize.Height;
var rgb = new byte[width * height * 4];
var partitions = Partitioner.Create(0, height);
Parallel.ForEach(partitions, range =>
{
var (item1, item2) = range;
Parallel.For(item1, item2, y =>
{
for (var x = 0; x < width; x++)
{
var yIndex = x + width * y;
var currentPosition = yIndex * 4;
var uvIndex = uvPixelStride * (x / 2) + uvRowStride * (y / 2);
fixed (byte* rgbFixed = rgb)
fixed (byte* yValuesFixed = yValuesArr)
fixed (byte* uValuesFixed = uValuesArr)
fixed (byte* vValuesFixed = vValuesArr)
{
var rgbPtr = rgbFixed;
var yValues = yValuesFixed;
var uValues = uValuesFixed;
var vValues = vValuesFixed;
var yy = *(yValues + yIndex);
var uu = *(uValues + uvIndex);
var vv = *(vValues + uvIndex);
var rTmp = yy + vv * 1436 / 1024 - 179;
var gTmp = yy - uu * 46549 / 131072 + 44 - vv * 93604 / 131072 + 91;
var bTmp = yy + uu * 1814 / 1024 - 227;
rgbPtr = rgbPtr + currentPosition;
*rgbPtr = (byte) (rTmp < 0 ? 0 : rTmp > 255 ? 255 : rTmp);
rgbPtr++;
*rgbPtr = (byte) (gTmp < 0 ? 0 : gTmp > 255 ? 255 : gTmp);
rgbPtr++;
*rgbPtr = (byte) (bTmp < 0 ? 0 : bTmp > 255 ? 255 : bTmp);
rgbPtr++;
*rgbPtr = 255;
}
}
});
});
return rgb;
}您也可以在on my repo中找到它。您还可以在同一个repo上找到I rendered the output to SkiaSharp
对于在我的手机上运行的1440x1080的预览大小,这段代码大约需要120ms才能完成。即使所有其他部分都进行了优化,我最多也只能得到8fps。不,这不是我的硬件,因为内置的相机应用程序运行得很流畅。顺便说一句,1440x1080是我的ChooseOptimalSize算法的输出,它是我从android的Camera2应用程序接口的mono-droid示例中获得的。我不知道这是不是最好的方式,或者它是否缺乏检测fps和缩小预览大小以使其更快的逻辑。
发布于 2019-01-26 08:59:28
SkiaSharp是否支持图形处理器绘图?如果将摄影机连接到SurfaceTexture,则可以将预览帧用作GL纹理,并将它们高效地渲染到OpenGL场景中。
即使不是这样,你仍然可以通过将帧发送到图形处理器并使用类似glReadPixels的东西将它们读回中央处理器来获得更快的结果,因为这将在图形处理器中进行RGB转换。
https://stackoverflow.com/questions/54361369
复制相似问题