因为我的毕业设计,我正在使用Video4Linux2从相机中获取YUV420图像,并将它们解析到x264中(x264本身可以处理这些图像),然后通过Live555将编码后的流发送到无线网络上的客户端RTP / RTCP兼容的视频播放器。我试图在实时情况下完成所有这些操作,因此需要一个控制算法,但这不是本问题的范围。除了Live555之外,所有内容都是用C语言编写的。目前,我已接近完成视频编码,但想要提高性能。
说实话,我遇到了一些问题... 我试图避免使用V4L2的用户空间指针,而是使用mmap()。我正在编码视频,但由于它是YUV420格式,我一直在malloc新内存来保存Y'、U和V平面,以便供x264读取。我希望将这些变量保留为指向mmap的内存块的指针。
然而,V4L2设备只有一个文件描述符用于缓冲流,我需要将流分成三个符合YUV420标准的mmap变量,如下所示...
说实话,我遇到了一些问题... 我试图避免使用V4L2的用户空间指针,而是使用mmap()。我正在编码视频,但由于它是YUV420格式,我一直在malloc新内存来保存Y'、U和V平面,以便供x264读取。我希望将这些变量保留为指向mmap的内存块的指针。
然而,V4L2设备只有一个文件描述符用于缓冲流,我需要将流分成三个符合YUV420标准的mmap变量,如下所示...
buffers[n_buffers].y_plane = mmap(NULL, (2 * width * height) / 3,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset);
buffers[n_buffers].u_plane = mmap(NULL, width * height / 6,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset +
((2 * width * height) / 3 + 1) /
sysconf(_SC_PAGE_SIZE));
buffers[n_buffers].v_plane = mmap(NULL, width * height / 6,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset +
((2 * width * height) / 3 +
width * height / 6 + 1) /
sysconf(_SC_PAGE_SIZE));
"width"和"height"是视频的分辨率(例如640x480)。
据我了解,MMAP会像这样(伪代码)遍历文件:
fd = v4l2_open(...);
lseek(fd, buf.m.offset + (2 * width * height) / 3);
read(fd, buffers[n_buffers].u_plane, width * height / 6);
我的代码存放在这里的Launchpad Repo(了解更多背景): http://bazaar.launchpad.net/~alex-stevens/+junk/spyPanda/files (修订版11)
YUV420格式可以从此Wiki示意图清楚地看到: http://en.wikipedia.org/wiki/File:Yuv420.svg(我希望将Y、U和V字节分别拆分到每个mmap'ed内存中)
有人能解释一下如何从一个文件描述符中映射三个变量到内存,或者为什么我错了吗?或者甚至提示一个更好的想法来解析YUV420缓冲区到x264?:P
干杯!^^