尝试编写了一个基于 v4l2 的摄像头应用,目前仅仅实现从摄像头捕捉视频,然后本地回显。
有图有正相,先上效果图,其中左侧小点为预监窗口,右侧为经过 x264 压缩,tcp 传输,libavcodec 解压,再用 qt 显示的效果,延迟很低很低 :)
主要就是以下几个知识点:
1. v4l2接口:
2. X11的本地回显:
3. 使用 libswscale 进行拉伸:
4. 使用 libx264 压缩:
1. v4l2接口: 大眼一看, 密密丫丫的 VIDIOC_XXXX, 其实静下心来, 也没多少, 很清晰, 大体流程如下:
capture_open(name)
open /dev/video0 // 打开设备
check driver caps // 检查一些 caps
VIDIOC_REQBUFS // 使用 streaming mode, mmap mode, 分配
VIDIOC_QUERYBUF // 获取分配的buf, 并且mmap到进程空间
mmap
VIDIOC_QBUF // buf 入列
VIDIOC_STREAMON // 开始
使用的数据结构
struct Buffer
{
void *start;
size_t length;
};
typedef struct Buffer Buffer;
struct Ctx
{
int vid;
int width, height; // 输出图像大小
struct SwsContext *sws; // 用于转换
int rows; // 用于 sws_scale()
int bytesperrow; // 用于cp到 pic_src
AVPicture pic_src, pic_target; // 用于 sws_scale
Buffer bufs[2]; // 用于 mmap
};
typedef struct Ctx Ctx;