欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

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

程序员文章站 2022-05-16 21:21:46
...

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

今天尝试编写了一个基于 v4l2 的摄像头应用, 目前仅仅实现从摄像头捕捉视频, 然后本地回显.

照例先上效果图, 其中左侧小点为预监窗口, 右侧为经过 x264 压缩, tcp 传输, libavcodec 解压, 再用 qt 显示的效果., 延迟很低很低 :)

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

主要就是以下几个知识点:

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 显示实时图像