**已关闭。**此问题不符合Stack Overflow guidelines。当前不接受答案。
我们不允许问题寻求书籍、工具、软件库等的建议。您可以编辑问题,以便使用事实和引文来回答。
去年关闭了。
这篇文章3天前被编辑并提交审查。
Improve this question
我正在开发一个视频播放应用程序,它将逐帧显示包含原始平面图像数据的视频文件。它包含的数据是8位rgb(目前没有alpha).这里的硬件只接受隔行扫描的图像数据,因此我需要将平面图像数据转换成隔行扫描的图像数据,我所做的是对平面数据进行memmove或memcpy,但是在处理高清内容时,由于数据是原始数据,这将占用大量时间。我尝试使用两个线程来实现,一个用于处理,另一个用于显示。结果表明,显示处理过的交错数据确实很快,但处理线程无法跟上。因此,由于处理速度的原因,帧速率受到严重影响。
我确实有个想法,就是对所有内容进行预处理并保存在内存中(那些视频片段的帧数相对较少)。当需要时,我会将处理后的数据显示在内存中。实际上我测试了这种方法,它相当快(60 fps)。然而,这似乎是次优的,因为我要么会有一个真正缓慢的第一次运行,要么需要等待一段时间才开始播放。而且,当文件变大时,由于内存限制,无法做到这一点。
所以我正在寻找任何图像处理库或算法,做平面-〉交错快速。我确实尝试了gil从boost,但性能不是很好。
5条答案
按热度按时间r1zk6ea11#
我不得不解决同样的问题,但我有一个额外的约束,我需要执行转换“在适当的地方”(即,我必须离开图像数据在同一个缓冲区)。在下面的图像中,我演示了像素需要如何从平面移动到交错表示:
所以我们可以通过一系列的交换来改变图像。这是我的C++实现,它在线性时间内运行。模板参数
T
是图像通道类型(例如,uint8_t
表示字节大小的通道)。这里我将存储在缓冲区
image
(保存WH3个值)中的WxH RGB图像从平面转换为隔行扫描:不管怎么说,这很有趣。
4ngedf3f2#
(在我的注解旁边添加代码)
这是在2.4GHz英特尔酷睿2双核处理器上用g++ 4.2.1和-O2编译的,在10秒内运行2000帧。
注意,这样写可以让编译器更好地优化,而把它分成几行(或12字节的块)只会让运行速度变慢。
57hvy0tb3#
libswscale(ffmpeg的一部分)可以做到这一点,据我所知,一个很好的教程可以找到here
6yjfywim4#
使用矢量内部函数编写此函数应该非常简单。我不知道您使用的是什么处理器、编译器或压缩像素格式,因此我将使用x86的愚者和MMX内部函数给出一个示例实现。将此代码转换为ARM NEON、PowerPC Altivec或x86/x64 SSE代码也应该很容易。
这应该可以将RGB平面转换为32位RGBA压缩,尽管ARGB实际上更常见。如果你需要24位RGB,你就得有点创意。在编写这段代码时,处理器的《软件开发手册》将是你最好的朋友,你也需要阅读编译器的文档。
SIMD非常好地处理了这一点,你可以从下面的代码有多短来判断。注意,下面的代码实际上是C99,而不是C++,因为C99可以访问
restrict
关键字,这可以减少生成的加载和存储的数量。还请注意,此代码具有严格的对齐要求。
von4xj4u5#
有一个Simd Library,它有很多图像转换的算法,它支持以下图像格式之间的转换:NV 12、YUV 420 P、YUV 422 P、YUV 444 P、BGR-24、BGRA-32、HSL-24、HSV-24、Gray-8、Bayer等。这些算法通过使用不同的SIMD CPU扩展进行了优化。特别是,该库支持以下CPU扩展:适用于x86/x64的SSE、SSE 2、SSSE 3、SSE4.1、SSE4.2、AVX和AVX 2,以及适用于PowerPC的VMX(Altivec)和VSX(Power 7)。