基于RTMP推送实时AAC+H264流(一)

本文介绍了在Linux环境下使用v4l2和alsa进行图像和声音采集,通过YUYV2I420、YUYV2RGB24处理,结合x264编码和RTMP推送实时AAC+H264流的流程。详细讲解了采集、处理、编码和封装的步骤,并提及了动态检测的初步应用。
摘要由CSDN通过智能技术生成

最近在做视频监控的项目,搞了一个多星期,总结一下学到的东西,也希望可以帮到有需要的人
从整体来看,推流端大概是这么个流程:采集、处理、编码、封装、推送
rtmp
如上图所示,图像采集线程和声音采集线程经过编码封装,将RTMP包写入到缓冲队列,发送线程从缓冲队列中读取RTMP包中并加上时间戳,然后送往RTMP服务器,由于一秒可能有上百个RTMP包,会造成大量的new和delete,所以实现了一个简单的内存池以减少内存分配及释放的次数

采集

分为图像和声音,采集图像用的是v4l2 API,采集声音用的是alsa API,这两个都是linux环境下的,暂时没有考虑其他环境

v4l2

流程:打开设备、检查设备能力、设置格式、设置缓冲区、读取缓冲队列
详细代码位于V4L2Source.cpp,当然也可以看官方Demo
打开设备:首先是打开设备文件,也可以用非阻塞的方式打开,但接下来的相关IO操作也是非阻塞的

fd = open("/dev/video0", O_RDWR);

检查设备能力:通过 V4L2_CAP_VIDEO_CAPTURE 位来判断设备是否具有捕获图像的能力

v4l2_capability cap;
ioctl(fd, VIDIOC_QUERYCAP, &cap);
if(!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
    return false;
}

设置格式:这一步之前可能需要检查一下摄像头支持的格式,检查需要用到ioctl函数和VIDIOC_ENUM_FMT参数,这里略过了这一步,统一设置成了支持较多的YUYV,也叫YUY2,然后编码前再把图片转为所需格式

v4l2_format fmt;

fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = width;
fmt.fmt.pix.height = height;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.field = V4L2_FIELD_NONE;

ioctl(fd, VIDIOC_S_FMT, &fmt);
if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_YUV420) {
    return false;
}

设置缓冲区:缓冲区是一个队列,用于接收图像数据,这里用mmap的方式,将内核空间的内存映射到用户空间,这样可以避免拷贝,这里首先需要定义一个结构体来保存返回缓冲区的位置和大小

v4l2_requestbuffers reqbuf;
v4l2_buffer buf;

reqbuf.count = 4;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf.memory = V4L2_MEMORY_MMAP;
ioctl(fd, VIDIOC_REQBUFS, &reqbuf);

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值