使用live555 直播来自v4l2的摄像头数据
使用live555 直播来自v4l2的摄像头数据,在我的这个工程中,基本思路是:使用V4L2采集摄像头数据,然后使用x264库对摄像头数据进行编码,编成H264数据格式,然后把数据写入到命名管道中。最后使用live555 从管道中读出数据发送出去,实现视频的直播。
在我的工程调试过程中,使用的是罗技C270摄像头,出来的是YUYV数据格式。x264和live555 使用最新的库。工程目录如下:
├── H264FramedLiveSource.cpp
├── H264VideoStreamer.cpp
├── include
│ ├── encoder
│ │ ├── encoder_define.hh
│ │ ├── H264FramedLiveSource.hh
│ │ └── stdint.h
│ ├── live555
│ │ ├── basicUsageEnvironment
│ │ ├── groupsock
│ │ ├── liveMedia
│ │ └── usageEnvironment
│ └── x264
│ ├── x264_config.h
│ └── x264.h
├── lib
│ ├── livelib
│ │ ├── libBasicUsageEnvironment.a
│ │ ├── libgroupsock.a
│ │ ├── libliveMedia.a
│ │ └── libUsageEnvironment.a
│ └── x264lib
│ ├── libx264.a
│ └── libx264.so.148
└── Makefile
H264FramedLiveSource.cpp 中新建了一个Device 类,用来实现v4l2数据的采集和x264编码的实现。其函数定义如下:
/*=============================================================================* # FileName: H264FramedLiveSource.hh* # Desc: * # * # Author: licaibiao* # Version: * # LastChange: 2017-02-24 * =============================================================================*/
#ifndef _H264FRAMEDLIVESOURCE_HH
#define _H264FRAMEDLIVESOURCE_HH
#include <FramedSource.hh>
#include <UsageEnvironment.hh>
#include "encoder_define.hh"class Device
{
public:void init_mmap(void);void init_camera(void);void init_encoder(void);void open_camera(void); void close_camera(void);void read_one_frame(void);void getnextframe(void);void start_capture(void);void stop_capture(void);void close_encoder(); int camera_able_read(void);void compress_begin(Encoder *en, int width, int height);int compress_frame(Encoder *en, int type, char *in, int len, char *out);void compress_end(Encoder *en);void Init();void intoloop();;void Destory();
public:int fd;FILE *save_fd;int n_nal;int frame_len;char *h264_buf;unsigned int n_buffer;Encoder en;FILE *h264_fp;BUFTYPE *usr_buf;FILE *pipe_fd;
};
#endif
H264VideoStreamer.cpp 实现RTSP的创建。其代码实现如下:
/**********
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more details.You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
**********/
// Copyright (c) 1996-2017, Live Networks, Inc. All rights reserved
// A test program that reads a H.264 Elementary Stream video file
// and streams it using RTP
// main program
//
// NOTE: For this application to work, the H.264 Elementary Stream video file *must* contain SPS and PPS NAL units,
// ideally at or near the start of the file. These SPS and PPS NAL units are used to specify 'configuration' information
// that is set in the output stream's SDP description (by the RTSP server that is built in to this application).
// Note also that - unlike some other "*Streamer" demo applications - the resulting stream can be received only using a
// RTSP client (such as "openRTSP")#include <liveMedia.hh>
#include <BasicUsageEnvironment.hh>
#include <GroupsockHelper.hh>
#include <H264FramedLiveSource.hh>
#include <sys/types.h>
#include <sys/stat.h> UsageEnvironment* env;
char const* inputFileName = "/tmp/fifo";
char *ptr;
H264VideoStreamFramer* videoSource;
RTPSink* videoSink;
class Device Camera; void play(); // forwardEventTriggerId DeviceSource::eventTriggerId = 0;int main(int argc, char** argv) {// Begin by setting up our usage environment:TaskScheduler* scheduler = BasicTaskScheduler::createNew();env = BasicUsageEnvironment::createNew(*scheduler);// Create 'groupsocks' for RTP and RTCP:struct in_addr destinationAddress;destinationAddress.s_addr = chooseRandomIPv4SSMAddress(*env);// Note: This is a multicast address. If you wish instead to stream// using unicast, then you should use the "testOnDemandRTSPServer"// test program - not this test program - as a model.const unsigned short rtpPortNum = 18888;const unsigned short rtcpPortNum = rtpPortNum+1;const unsigned char ttl = 255;const Port rtpPort(rtpPortNum);const Port rtcpPort(rtcpPortNum);Camera.Init();mkfifo(inputFileName, 0777);if(0 == fork()){Camera.pipe_fd = fopen(inputFileName, "w");if(NULL == Camera.pipe_fd){printf("===============child process open pipe err =======\n ");}while(1){usleep(15000);Camera.getnextframe();}}Groupsock rtpGroupsock(*env, destinationAddress, rtpPort, ttl);rtpGroupsock.multicastSendOnly(); // we're a SSM sourceGroupsock rtcpGroupsock(*env, destinationAddress, rtcpPort, ttl);rtcpGroupsock.multicastSendOnly(); // we're a SSM source// Create a 'H264 Video RTP' sink from the RTP 'groupsock':OutPacketBuffer::maxSize = 600000;videoSink = H264VideoRTPSink::createNew(*env, &rtpGroupsock, 96);// Create (and start) a 'RTCP instance' for this RTP sink:const unsigned estimatedSessionBandwidth = 10000; // in kbps; for RTCP b/w shareconst unsigned maxCNAMElen = 100;unsigned char CNAME[maxCNAMElen+1];gethostname((char*)CNAME, maxCNAMElen);CNAME[maxCNAMElen] = '\0'; // just in caseRTCPInstance* rtcp= RTCPInstance::createNew(*env, &rtcpGroupsock,estimatedSessionBandwidth, CNAME,videoSink, NULL /* we're a server */,True /* we're a SSM source */);// Note: This starts RTCP running automaticallyRTSPServer* rtspServer = RTSPServer::createNew(*env, 8554);if (rtspServer == NULL) {*env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";exit(1);}ServerMediaSession* sms= ServerMediaSession::createNew(*env, "testStream", inputFileName,"Session streamed by \"testH264VideoStreamer\"",True /*SSM*/);sms->addSubsession(PassiveServerMediaSubsession::createNew(*videoSink, rtcp));rtspServer->addServerMediaSession(sms);char* url = rtspServer->rtspURL(sms);*env << "Play this stream using the URL \"" << url << "\"\n";delete[] url;// Start the streaming:*env << "Beginning streaming...\n";play();env->taskScheduler().doEventLoop(); // does not returnreturn 0; // only to prevent compiler warning
}void afterPlaying(void* /*clientData*/) {*env << "...done reading from file\n";videoSink->stopPlaying();Medium::close(videoSource);Camera.Destory();// Note that this also closes the input file that this source read from.// Start playing once again:play();
}void play() {// Open the input file as a 'byte-stream file source':ByteStreamFileSource* fileSource= ByteStreamFileSource::createNew(*env, inputFileName);if (fileSource == NULL) {*env << "Unable to open file \"" << inputFileName<< "\" as a byte-stream file source\n";exit(1);}FramedSource* videoES = fileSource;// Create a framer for the Video Elementary Stream:videoSource = H264VideoStreamFramer::createNew(*env, videoES);// Finally, start playing:*env << "Beginning to read from file...\n";videoSink->startPlaying(*videoSource, afterPlaying, videoSink);
}
x264 和live555库的下载编译安装,在前面的博客中已经讲过,这里不再重复。编译运行整个工程如下:
[root@redhat pipelive]# ls
H264FramedLiveSource.cpp H264FramedLiveSource.o H264VideoStreamer H264VideoStreamer.cpp H264VideoStreamer.o include lib Makefile
[root@redhat pipelive]# ./H264VideoStreamercamera driver name is : uvcvideo
camera device name is : UVC Camera (046d:0825)
camera bus information: usb-0000:00:1a.0-1.1
n_buffer = 4
x264 [warning]: lookaheadless mb-tree requires intra refresh or infinite keyint
x264 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
x264 [info]: profile High 4:2:2, level 3.0, 4:2:2 8-bit
Play this stream using the URL "rtsp://192.168.0.127:8554/testStream"
Beginning streaming...
Beginning to read from file...
在VLC 播放器中打开网络流rtsp://192.168.0.127:8554/testStream 可以看到摄像头中的数据:
实际测试,使用管道来传输摄像头数据会出现一些延时,如果图片尺寸设置在320*240 延时会很小,但是图片尺寸设置在640*480,延时现象就会非常明显。这与我使用的摄像头也有关系,UVC摄像头读取数据相对会比较慢。
完整的工程可以从这里下载:live555直播来自v4l2 的摄像头数据
================2018-03-16 更新==================
因为工程中包含x264动态库等文件,某网友下载工程文件后被他电脑某杀毒软件报病毒......
结果那家伙居然回来举报我........ 艹 被举报之后下载链接就失效了.......
如果有需要工程代码做参考的可以在评论区留个邮箱,看到后会邮件发送给有需要者。
=================2018-05-14更新======================
代码可以到GitHub 上自行获取, 代码路径:https://github.com/licaibiao/live555_rtsp_live_v4l2
=================2020-01-16更新======================
更新GitHub地址:GitHub - licaibiao/v4l2_video_audio_encode_live
之前代码仓目录已经被调整了。
------------------------------------------2022.08.21------------------------------------------
该博客将停止更新
新的文章内容和附件工程文件
请到 liwen01博客首页信息查询
------------------------------------------2022.08.21------------------------------------------
使用live555 直播来自v4l2的摄像头数据相关推荐
- 使用 live555 直播来自 v4l2 的摄像头图像
结合前面的 采集 v4l2 视频, 使用 live555, 通过 rtsp 发布实时流. capture.h, capture.cpp, vcompress.h, vcompress.cpp 需要参考 ...
- FFMPEG(一) 从V4L2捕获摄像头数据
系列相关博文: FFMPEG(一) 从V4L2捕获摄像头数据 FFMPEG(二) v4l2 数据格式装换 FFMPEG(三) v4l2 数据编码H264 最近在学习FFMPEG,发现网上的很多例子都是 ...
- V4L2视频采集与H264编码1—V4L2采集JPEG数据
最近在做视频编码,经过一段时间的折腾,终于可以把V4L2采集到的图片数据编码成H264视频,并且成功将工程移植到了ARM开发板上.无奈开发板性能太低,每秒钟只能编码一帧数据,查看CPU已经跑到100% ...
- live555 直播
摄像头采集,264编码,live555直播(1) http://www.cnblogs.com/mlj318/archive/2013/01/23/2872932.html 重载FrameSource ...
- CenterFusion:融合雷达与摄像头数据的高精度3D目标检测
点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 编辑丨我爱计算机视觉 介绍一篇新出的论文 CenterFusion: Center-based Rad ...
- 【Android RTMP】NV21 图像旋转处理 ( 快速搭建 RTMP 服务器 Shell 脚本 | 创建 RTMP 服务器镜像 | 浏览器观看直播 | 前置 / 后置摄像头图像旋转效果展示 )
文章目录 安卓直播推流专栏博客总结 一. 编写快速搭建 RTMP 服务器 Shell 脚本 二. RTMP 快速搭建方法 三.创建阿里云 RTMP 服务器镜像 四.浏览器查看直播内容 五.前置 / 后 ...
- V4L2采集视频数据
Video for Linux two(Video4Linux2)简称V4L2,是V4L的改进版.V4L2是linux操作系统下用于采集图片.视频和音频数据的API接口,配合适当的视频采集设备和相应的 ...
- ffmpeg推流摄像头数据至公网服务器
完整的推流代码已经托管到个人的Gitee,如有需要请自取 https://gitee.com/MonsterAKALei/push_video.git ffmpeg推流摄像头数据 昨天实现用API分别 ...
- win摄像头怎么在linux,如何利用Video4Linux获取摄像头数据
Video4Linux是Linux下用于获取视频和音频数据的API接口,在这篇文章中,着重阐述如何利用Video4Linux获取摄像头数据,以实现连续影像的播放. 1. 摄像头的安装 在 Linux下 ...
最新文章
- SparkSQL入门_1
- stitching detail输出的dot图含义
- 手工部署Sqlserver CLR程序集
- 为什么不用简书写文章
- axios (get post请求、头部参数添加)傻瓜式入门axios
- java arraylist length,在Java中调整ArrayList的大小时,无法理解溢出的可能性
- js 中的属性以数字开头的属性和取值
- 无人车创业正驶入分水岭
- android系统签名
- Pandas速查手册中文版(转)
- Unity中使用VideoPlayer控制播放暂停进度条
- 五、鼎捷T100生产管理之报工
- Unity实现打地鼠游戏操作步骤、总结、问题及解决办法
- this在什么时候为undefined
- 文献阅读——梅州佛教香花的结构、文本与变体
- echart 环形饼图设置中心固定信息
- 如何将阿里云旧服务器上的数据转移到新服务器上
- shell的转义字符
- 6.网络安全渗透测试—[信息收集篇6]—[Email信息收集]
- [C语言]输出100以内的所有素数(质数)