linux下live555编译和调试
liveMedia项目(http://www.live555.com/)
1、编译安装
make
2、运行
cd mediaServer
./live555MediaServer
可以看到支持的文件格式是不包括 .264 的。(关于其它格式请参考我的另一篇博文)
3、live555 模块分析
分为四个基本库 :UsageEnvironment&TaskScheduler, groupsock, liveMedia和BasicUsageEnvironment
UsageEnvironment和TaskScheduler类用于事件的调度,实现异步读取事件的句柄的设置以及错误信息的输出。另外,还有 一个HashTable类定义了一个通用的hash表,其它代码要用到这个表。这些都是抽象类,在应用程序中基于这些类来实现自己的子类。
groupsock类是对网络接口的封装,用于收发数据包。正如名字本身,groupsock主要是面向多播数据的收发的,它也同时支持单播数据 的收发。
liveMedia库中有一系列类,基类是Medium,这些类针对不同的流媒体类型和编码。
备注:在支持 h.264 的过程中,主要是修改这个目录下,需要添加一些文件
各种测试代码在testProg目录下,这个目录下的测试很多要求组播,组播环境比较难搭建(当然排除你是搞网络的),所以,建议测试 testOnDemandRTSPServer
测试步骤:
1、./testOnDemandRTSPServer
这时,你会看到它的提示,不要着急去测试,先把你测试所需的媒体文件丢到 testProg 目录下
2、建议客户端使用 vlc 测试, vlc 在 linux 下 apt-get 即可,在 windows 下也有相应版本
3、测试过程中,为了提高效率,建议使用抓包工具 ,推荐使用 wireshark ,在 linux 下 source code 编译安装,在 windows 下有相应版本
4、live555 概述
Media Server是一个纯粹的RTSP服务器。支持多种格式的媒体文件(在我的另一篇博文中有提到为什么强调“支持”)
5、用live555开发必备概念
基于liveMedia的程序,需要通过继承UsageEnvironment抽象类和TaskScheduler抽象类,定义相应的类来处理事 件调度,数据读写以及错误处理。live项目的源代码里有这些类的一个基本实现,这就是“BasicUsageEnvironment”库。 BasicUsageEnvironment主要是针对简单的控制台应用程序,利用select实现事件获取和处理。这个库利用Unix或者 Windows的控制台作为输入输出,处于应用程序原形或者调试的目的,可以用这个库用户可以开发传统的运行与控制台的应用。
通过使用自定义的“UsageEnvironment”和“TaskScheduler”抽象类的子类,这些应用程序就可以在特定的环境中运行, 不需要做过多的修改。需要指出的是在图形环境(GUI toolkit)下,抽象类 TaskScheduler 的子类在实现 doEventLoop()的时候应该与图形环境自己的事件处理框架集成。
一些重要的东东:
Sink -- 就是消费数据的对象,比如把接收到的数据存储到文件, 这个文件就是一个Sink。
Source -- 就是生产数据的对象,比如通过RTP读取数据。
Framer
Parser
Session -- 这主要是因为 rtsp 是有状态的
备注:
从其它Source接收数据的source也叫做"filters"。
Module是一个sink或者一个filter。
数据接收的终点是 Sink类,MediaSink是所有Sink类的基类。
Sink类实现对数据的处理是通过实现纯虚函数continuePlaying(),通常情况下 continuePlaying调用fSource->getNextFrame来为Source设置数据缓冲区,处理数据的回调函数 等,fSource是MediaSink的类型为FramedSource*的类成员。
但如果你有硬编码硬件生成的媒体文件,并且不需要实时播放,那么 Source 就是可以没有的。
6、liveMedia的应用程序的控制流程
1)RTSP连接的建立过程
RTSPServer 用类 DynamicRTSPServer :: CreateNew (* env ,rtspServerPortNum ,authDB) 实现。
建立 Socket(ourSocket)在TCP的554端口进行监听,然后把连接处理函数句柄 (RTSPServer::incomingConnectionHandler)和socket句柄传给任务调度器(taskScheduler)。
这里,使用了 linux 下有名 的 select 模型,taskScheduler 把 554 的 socket 放到了 readset 中 ,同时将 socket句柄和incomingConnectionHandler句柄 相关联,然后 main 函数进入 env.taskScheduler.doEventLoop
select 函数只是返回此时是否有 socket 准备好读写,然后,遍历 handlerset 用FD_ISSET 判断是否 handler 所掌管的 socket 可以用了。如前面提到的incomingConnectionHandler了。在 incomingConnectionHandler中创建了RTSPClientSession,开始对这个客户端的会话进行处理。
2)DESCRIBE请求消息处理过程
RTSP服务器收到客户端的DESCRIBE请求后,根据请求URL(rtsp://192.168.1.109/1.mpg),找到对应的流媒体资源, 返回响应消息。live555中的ServerMediaSession类用来处理会话中描述,它包含多个(音频或视频)的子会话描述 (ServerMediaSubsession)。
创建的 RTSPClientSession ,会有一个新的 socket 在 新的 port 上监听,同时,也会有 incomingConnectionHandler ,就是说类似于 554 的处理过程 ,不过这个incomingConnectionHandler 是属于 RTSPClientSession 的,在这个 incomingConnectionHandler 中,就有根据 cmdName ,执行不同的 Handler,如 handleCmd_DESCRIBE。此时,通过 url 去确定,产生哪种类型的 subsession ,在一个Session 下可以有多个 subsession ,且它们形成链表,比如在看 mpg 文件的时候,mpg 既包括一个 video 的 subsession 又包括一个 audio 的 subsession (这样也就不难解决 h.264 视频编码和 g.711 音频编码同时播放的问题,它们在一个ServerMediaSession 中的 subSession 中)
这里,还需要提一下 ServerMediaSession 和 RTSPClientSession 的关系,RTSPClientSession 与 socket、handler 关联 ,标记一次 rtsp 的过程,而在该链接处理 DESCRIBE 信令时 ,产生ServerMediaSession ,标记 Server 端所能提供的媒体会话。
3)SETUP
前面已经提到RTSPClientSession类,用于处理单独的客户会话。其类成员函数handleCmd_SETUP()处理客户端的SETUP请 求。调用parseTransportHeader()对SETUP请求的传输头解析,调用子会话(这里具体实现类为 OnDemandServerMediaSubsession)的getStreamParameters()函数获取流媒体发送传输参数。将这些参数组 装成响应消息,返回给客户端。
获取发送传输参数的过程:调用子会话(具体实现类MPEG1or2DemuxedServerMediaSubsession)的 createNewStreamSource(...)创建MPEG1or2VideoStreamFramer,选择发送传输参数,并调用子会话的 createNewRTPSink(...)创建MPEG1or2VideoRTPSink。同时将这些信息保存在StreamState类对象中,用于 记录流的状态。
客户端发送两个SETUP请求,分别用于建立音频和视频的RTP接收。
4)PLAY请求消息处理过程
RTSPClientSession类成员函数handleCmd_PLAY()处理客户端的播放请求。首先调用子会话的startStream(),内 部调用MediaSink::startPlaying(...),然后是 MultiFramedRTPSink::continuePlaying(),接着调用 MultiFramedRTPSink::buildAndSendPacket(...)。buildAndSendPacke内部先设置RTP包头, 内部再调用MultiFramedRTPSink::packFrame()填充编码帧数据。
packFrame内部通过 FramedSource::getNextFrame(), 接着MPEGVideoStreamFramer::doGetNextFrame(),再接着经过 MPEGVideoStreamFramer::continueReadProcessing(), FramedSource::afterGetting(...), MultiFramedRTPSink::afterGettingFrame(...), MultiFramedRTPSink::afterGettingFrame1(...)等一系列繁琐调用,最后到了 MultiFramedRTPSink::sendPacketIfNecessary(), 这里才真正发送RTP数据包。然后是计算下一个数据包发送时间,把MultiFramedRTPSink::sendNext(...)函数句柄传给任务 调度器,作为一个延时事件调度。在主循环中,当MultiFramedRTPSink::sendNext()被调度时,又开始调用 MultiFramedRTPSink::buildAndSendPacket(...)开始新的发送数据过程,这样客户端可以源源不断的收到服务器传 来的RTP包了。
7、添加文件,修改 live555 支持 h.264
H264VideoStreamFramer: A filter that breaks up an H264 video stream into headers and frames
StreamParser: Abstract class for parsing a byte stream
H264VideoStreamParser: Class for parsing H264Video stream
ByteStreamFileSource: A file source that is a plain byte stream (rather than frames)
StreamState:A class that represents the state of an ongoing stream
H264VideoRTPSink
H264VideoFileServerMediaSubsession
linux下live555编译和调试的更多相关文章
- linux 下cmake 编译 ,调用,调试 poco 1.6.0 小记
上篇文章 小记了: 关于 Poco::TCPServer框架 (windows 下使用的是 select模型) 学习笔记. http://www.cnblogs.com/bleachli/p/4352 ...
- LINUX下文件编译
body, table{font-family: 微软雅黑} table{border-collapse: collapse; border: solid gray; border-width: 2p ...
- 【流媒體】live555—VS2008 下live555编译、使用及测试
[流媒體]live555—VS22008 下live555编译.使用及测试 Ⅰ live555简介 Live555 是一个为流媒体提供解决方案的跨平台的C++开源项目,它实现了对标准流媒体传输协议如R ...
- [转] linux下的c/c++调试器gdb
PS:1. 断点C++类函数,用b 命名空间::类名::方法名 2. 编译参数一定要加-g,才可断点调试 http://www.cnblogs.com/xd502djj/archive/2012/08 ...
- FFmpeg在Linux下安装编译过程
转载请把头部出处链接和尾部二维码一起转载,本文出自:http://blog.csdn.net/hejjunlin/article/details/52402759 今天介绍下FFmpeg在Linux下 ...
- linux下的c/c++调试器gdb
Reference: http://www.cnblogs.com/xd502djj/archive/2012/08/30/2663960.html linux下的c/c++调试器gdb gdbLi ...
- 从四个问题透析Linux下C++编译&链接
摘要:编译&链接对C&C++程序员既熟悉又陌生,熟悉在于每份代码都要经历编译&链接过程,陌生在于大部分人并不会刻意关注编译&链接的原理.本文通过开发过程中碰到的四个典型 ...
- ACE-6.1.0 linux 下的编译与安装步骤
ACE-6.1.0 linux 下的编译与安装步骤 引用至http://www.cnblogs.com/liangxiaxu/archive/2013/03/07/2948417.html 1.从 ...
- Linux下nginx编译安装教程和编译参数详解
这篇文章主要介绍了Linux下nginx编译安装教程和编译参数详解,需要的朋友可以参考下 一.必要软件准备1.安装pcre 为了支持rewrite功能,我们需要安装pcre 复制代码代码如下: # y ...
- Linux下使用GDB进行调试
Linux下使用GDB进行调试的常用命令记于此. $ sudo su # g++ -g test.cpp -o test -pthread # gdb test <------- ...
随机推荐
- tensorflow的断点续训
tensorflow的断点续训 2019-09-07 顾名思义,断点续训的意思是因为某些原因模型还没有训练完成就被中断,下一次训练可以在上一次训练的基础上继续训练而不用从头开始:这种方式对于你那些训练 ...
- Js 代码递归实现树形数据与数组相互转换。
贴代码: // Grid->Tree 结构组装. var tree = []; this.setTreeData(table, tree, ""); //组装树形 setTr ...
- Eclipse导入第四版《算法》algs4库
最近在研究<算法>,遇到algs4库导入eclipse问题,查了很多网站,都不适用,最终解决,特此记录一下.第一次写博客,有什么不足之处望各位大神纠正. 1. 首先打开eclipse软件, ...
- 使用虚拟 dom 渲染页面 《vue.js 设计与实现》
使用 js 对象描述 ui 更加灵活.假如我们要根据级别不同采用不同的标签.js 对象描述的话,只需要一个变量代表 h 标签即可. // 当变量改变时,标签也会变化. let level = 3 c ...
- ubuntu主机连接家里的网线
第一步,先让物理机连接网络: 注释掉/etc/network/interfaces文件的最后一行,即: 意思是不要手动设置网络了,而是转为自动设置.这样,主机就可以联网了. 参考链接:https:// ...
- decay_rate, decay_steps ,batchsize,iteration,epoch
(96条消息) decay_rate, decay_steps ,batchsize,iteration,epoch_hellocsz的博客-CSDN博客_decay_steps (1)batchsi ...
- DataX Web可视化分布式调度数据同步系统
因项目需要,结合目前参与的项目,以及个人技术能力范围,组合研发一套web可视化数据同步系统,正式名称:DataXP. 项目背景:接触过阿里云这类大数据平台,对于中大型项目以及需要与外部系统对接数据的情 ...
- vue项目 - 自定义数字输入指令 | 限制自定义小数位输入
1.在main.js中直接加入代码: import Vue from 'vue' Vue.directive("input-limit", { bind(el, binding) ...
- 安装opencv相关
1.查看当前OpenCV的版本 pkg-config --modversion opencv 2.查找有关OpenCV文件 find / -iname "*opencv*" //- ...
- 第二章启动引导器GRUB2
第二章启动引导器GRUB2grub的配置文件路径:vim /boot/grub2/grub.cfg (不建议直接编辑)vim /etc/default/grub (可编辑的文件)将编辑的操作刷新到/b ...