首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何加快YUV转换为快速的SkiaSharp相机预览?

如何加快YUV转换为快速的SkiaSharp相机预览?
EN

Stack Overflow用户
提问于 2019-01-25 16:16:44
回答 1查看 251关注 0票数 0

我正在写一些使用SkiaSharp渲染相机预览的代码。这是跨平台的,但我在为android编写实现时遇到了一个问题。

我需要将YUV_420_888转换为RGB8888,因为这是SkiaSharp所支持的,并且在this thread的帮助下,以某种方式设法在我的SkiaSharp画布上显示了相当高质量的图像。问题出在速度上。在最好的情况下,我可以得到大约8fps,但通常只有4到5fps。事实证明,最大的因素是转换。我现在有大约3个版本的ToRGB转换器。我甚至尝试过“不安全”代码和并行循环。我会给你看我最好的一张。

代码语言:javascript
复制
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和缩小预览大小以使其更快的逻辑。

EN

回答 1

Stack Overflow用户

发布于 2019-01-26 08:59:28

SkiaSharp是否支持图形处理器绘图?如果将摄影机连接到SurfaceTexture,则可以将预览帧用作GL纹理,并将它们高效地渲染到OpenGL场景中。

即使不是这样,你仍然可以通过将帧发送到图形处理器并使用类似glReadPixels的东西将它们读回中央处理器来获得更快的结果,因为这将在图形处理器中进行RGB转换。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54361369

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档