資源簡介
一個webcam_v4l2的演示:包含兩部分:
1. webcam_server: 抓v4l2, 壓縮,發(fā)送
2. webcam_shower: 接收,解壓,回放
代碼片段和文件信息
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
extern?“C“?{
# include?
# include?
}
#include?“capture.h“
struct?Buffer
{
void?*start;
size_t?length;
};
typedef?struct?Buffer?Buffer;
struct?Ctx
{
int?vid;
int?width?height; //?輸出圖像大小
struct?SwsContext?*sws; //?用于轉(zhuǎn)換
int?rows; //?用于?sws_scale()
int?bytesperrow;?//?用于cp到?pic_src
AVPicture?pic_src?pic_target; //?用于?sws_scale
Buffer?bufs[2]; //?用于?mmap
????????PixelFormat?fmt;
};
typedef?struct?Ctx?Ctx;
int?capture_get_output_ptr?(void?*c?unsigned?char***ptr?int?**ls)
{
????Ctx?*ctx?=?(Ctx*)c;
????*ptr?=?ctx->pic_target.data;
????*ls?=?ctx->pic_target.linesize;
????return?1;
}
void?*capture_open?(const?char?*dev_name?int?t_width?int?t_height?PixelFormat?tarfmt)
{
int?id?=?open(dev_name?O_RDWR);
if?(id?0)?return?0;
Ctx?*ctx?=?new?Ctx;
ctx->vid?=?id;
//?to?query?caps
v4l2_capability?caps;
ioctl(id?VIDIOC_QUERYCAP?&caps);
if?(caps.capabilities?&?V4L2_CAP_VIDEO_CAPTURE)?{
if?(caps.capabilities?&?V4L2_CAP_READWRITE)?{
//?TODO:?...
}
if?(caps.capabilities?&?V4L2_CAP_STREAMING)?{
//?檢查是否支持?MMAP?還是?USERPTR
v4l2_requestbuffers?bufs;
memset(&bufs?0?sizeof(bufs));
bufs.count?=?2;
bufs.type?=?V4L2_BUF_TYPE_VIDEO_CAPTURE;
bufs.memory?=?V4L2_MEMORY_MMAP;
if?(ioctl(id?VIDIOC_REQBUFS?&bufs)?0)?{
fprintf(stderr?“%s:?don‘t?support?MEMORY_MMAP?mode!\n“?__func__);
close(id);
delete?ctx;
return?0;
}
fprintf(stderr?“%s:?using?MEMORY_MMAP?mode?buf?cnt=%d\n“?__func__?bufs.count);
//?mmap
for?(int?i?=?0;?i?2;?i++)?{
v4l2_buffer?buf;
memset(&buf?0?sizeof(buf));
buf.type?=?bufs.type;
buf.memory?=?bufs.memory;
if?(ioctl(id?VIDIOC_QUERYBUF?&buf)?0)?{
fprintf(stderr?“%s:?VIDIOC_QUERYBUF?ERR\n“?__func__);
close(id);
delete?ctx;
return?0;
}
ctx->bufs[i].length?=?buf.length;
ctx->bufs[i].start?=?mmap(0?buf.length?PROT_READ|PROT_WRITE
MAP_SHARED?id?buf.m.offset);
}
}
else?{
fprintf(stderr?“%s:?can‘t?support?read()/write()?mode?and?streaming?mode\n“?__func__);
close(id);
delete?ctx;
return?0;
}
}
else?{
fprintf(stderr?“%s:?can‘t?support?video?capture!\n“?__func__);
close(id);
delete?ctx;
return?0;
}
int?rc;
//?enum?all?support?image?fmt
v4l2_fmtdesc?fmt_desc;
uint32_t?index?=?0;
????????//?看起來?不支持?plane?fmt?直接使用?RGB?吧?然后使用?libswscale?轉(zhuǎn)換
#if?1
do?{
fmt_desc.index?=?index;
fmt_desc.type?=?V4L2_BUF_TYPE_VIDEO_CAPTURE;
rc?=?ioctl(id?VIDIOC_ENUM_FMT?&fmt_desc);
if?(rc?>=?0)?{
fprintf(stderr?“\t?support?%s\n“?fmt_desc.description);
}
index++;
}?while?(rc?>=?0);
#endif?//?0
v4l2_format?fmt;
fmt.type?=?V4L2_BUF_TYPE_VIDEO_CAPTURE;
rc?=?ioctl(id?VIDIOC_G_FMT?&fmt);
if?(rc?0)?{
評論
共有 條評論