【发布时间】:2015-04-16 15:18:36
【问题描述】:
我正在使用 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
- gop: 10
- max_b_frames: 1
【问题讨论】:
-
如果您能负担更多的带宽/内存来使用 RGBA8888 而不是 RGB888,那么它会容易得多。
-
也许 libswscale 可以为您快速完成...
标签: c++ multithreading video ffmpeg v4l2