• 大小: 9KB
    文件类型: .bz2
    金币: 1
    下载: 0 次
    发布日期: 2021-06-05
  • 语言: 其他
  • 标签: linux  XShm  v4l2  udp  h264  

资源简介

一个webcam_v4l2的演示:包含两部分: 1. webcam_server: 抓v4l2, 压缩,发送 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; // 用于转换
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 转换
#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) {

评论

共有 条评论