嘗試編寫了一個基於 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;