您的当前位置:首页正文

基于v4l2的webcam应用,本地预监

2020-11-09 来源:汇智旅游网

今天尝试编写了一个基于 v4l2 的摄像头应用, 目前仅仅实现从摄像头捕捉视频, 然后本地回显. 照例先上效果图, 其中左侧小点为预监窗口, 右侧为经过 x264 压缩, tcp 传输, libavcodec 解压, 再用 qt 显示的效果., 延迟很低很低 :) 主要就是以下几个知识点: 1.

今天尝试编写了一个基于 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 // 开始

使用的数据结构

capture_open(...) 打开设备

capture_get_pic()

VIDIOC_DQBUF // 出列,

sws_scale // 格式转换/拉伸到 PIX_FMT_YUV420P, 准备方便压缩

VIDIOC_QBUF // 重新入列

capture_get_picture(...) 从摄像头得到一帧图片

2. X11 的本地回显: 采用 XShm, 效率还行

vs_open ()

XOpenDisplay()

XCreateSimpleWindow()

XCreateGC()

XMapWindow()

XShmCreateImage()

shmget()

shmat()

使用的数据结构

vs_open(...) 打开设备

vs_show()

sws_scale() // 拉伸到当前窗口大小, 转换格式

XShmPutImage() // 显示, 呵呵, 真的很简单

vs_show(...) 主要代码都是处理窗口变化的

3. libswscale: 用于picture格式/大小转换, 占用cpu挺高 :), 用起来很简单, 基本就是

sws = sws_getContext(....);

sws_scale(sws, ...)

4. libx264 压缩: 考虑主要用于互动, 所以使用 preset=fast, tune=zerolatency, 320x240, 10fps, 300kbps, jj实测延迟很低, 小于 100ms

使用的数据结构

vc_open(...) 设置必要的参数, 打开编码器

vc_compress(...) 压缩, 如果成功, 得到串流

附上源码: 唉, 源码是不停更新的, csdn居然没有一个类似 git, svn 之类的仓库, 算了, 如果有人要, email吧.

main.cpp 主流程

capture.cpp, capture.h 获取 v4l2 的图像帧

vcompress.cpp vcompress.h 实现 x264 的压缩

vshow.cpp vsho.h 用 X11 显示实时图像

显示全文