gpt4 book ai didi

c++ - 如何并行化这个 for 循环以快速将 YUV422 转换为 RGB888?

转载 作者:行者123 更新时间:2023-11-28 02:29:40 24 4
gpt4 key购买 nike

我正在使用 v4l2 api 从 Microsoft Lifecam 抓取图像,然后通过 TCP 将这些图像传输到远程计算机。我还使用 ffmpeg API 将视频帧编码为 MPEG2VIDEO。这些录制的视频播放速度太快,这可能是因为没有捕获足够的帧以及 FPS 设置不正确。

以下是将 YUV422 源转换为 RGB888 图像的代码。此代码片段是我代码中的瓶颈,因为它需要将近 100 - 150 毫秒来执行,这意味着我无法在 1280 x 720 分辨率下记录超过 6 - 10 FPS。 CPU使用率也是100%。

for (int line = 0; line < image_height; line++) {
for (int column = 0; column < image_width; column++) {
*dst++ = CLAMP((double)*py + 1.402*((double)*pv - 128.0)); // R - first byte
*dst++ = CLAMP((double)*py - 0.344*((double)*pu - 128.0) - 0.714*((double)*pv - 128.0)); // G - next byte
*dst++ = CLAMP((double)*py + 1.772*((double)*pu - 128.0)); // B - next byte

vid_frame->data[0][line * frame->linesize[0] + column] = *py;

// increment py, pu, pv here

}

'dst' 然后被压缩为 jpeg 并通过 TCP 发送,'vid_frame' 被保存到磁盘。

与目前的 5-6 FPS 相比,如何使此代码片段更快,以便在 1280x720 分辨率下至少获得 30 FPS?

我已经尝试使用 p_thread 跨三个线程并行化 for 循环,在每个线程中处理三分之一的行。

for (int line = 0; line < image_height/3; line++) // thread 1
for (int line = image_height/3; line < 2*image_height/3; line++) // thread 2
for (int line = 2*image_height/3; line < image_height; line++) // thread 3

这只给我每帧 20-30 毫秒的微小改进。并行化此类循环的最佳方法是什么?我可以使用 GPU 计算或类似 OpenMP 的东西吗?假设生成大约 100 个线程来进行计算?

我还注意到与 Microsoft USB Lifecam 相比,我的笔记本电脑网络摄像头的帧速率更高。

以下是其他详细信息:

  • Ubuntu 12.04,ffmpeg 2.6
  • AMG-A8 四核处理器,6GB RAM
  • 编码器设置:
    • 编解码器:AV_CODEC_ID_MPEG2VIDEO
    • 比特率:4000000
    • time_base:(AVRational){1, 20}
    • pix_fmt: AV_PIX_FMT_YUV420P
    • 成功率:10
    • max_b_frames:1

最佳答案

如果您只关心 fps 而不是每帧 ms(延迟),另一种选择是每帧一个单独的线程。

线程并不是提高速度的唯一选择。您还可以执行整数运算而不是浮点运算。 SIMD 是一个选项。使用 sws_scale 等现有库可能会为您提供最佳性能。

确保您正在编译 -O3(或 -Os)。

确保禁用调试符号。

将重复的操作移出循环,例如

// compiler cant optimize this because another thread could change frame->linesize[0]
int row = line * frame->linesize[0];
for (int column = 0; column < image_width; column++) {
...
vid_frame->data[0][row + column] = *py;

您可以预先计算表格,因此循环中没有数学:

init() {
for(int py = 0; py <= 255 ; ++py)
for(int pv = 0; pv <= 255 ; ++pv)
ytable[pv][py] = CLAMP(pv + 1.402*(py - 128.0));
}

for (int column = 0; column < image_width; column++) {
*dst++ = ytable[*pv][*py];

仅举几个选项。

关于c++ - 如何并行化这个 for 循环以快速将 YUV422 转换为 RGB888?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29346677/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com