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 <------- ...
随机推荐
- centos7中Firefox安装Flash插件
第一步:先下载好Flash插件安装包,可以到Adobe官网下载.因为是linux 64位系统,所以要下个匹配的,我下载的是flash_player_npapi_linux.x86_64.tar.gz, ...
- SEGGER_RTT_printf()函数添加打印浮点数功能
SEGGER 的实时传输 (RTT) 是一种用于嵌入式应用程序中交互式用户 I/O 的技术.它以非常高的性能结合了 SWO 和半主机的优势.但是在笔者使用时(RTT v758版本),其暂时不支持浮点数 ...
- cmd查看对应端口使用情况
cmd查看端口号netstat -ano | findstr 80
- RPA的概念和优势
大多数人每天都会使用到一些机器人流程自动化的工具,例如读取邮件和系统,计算.生成文件和报告.而在未来,那些你不想做的枯燥的工作,也许真的可以不做了,重复化.标准化的工作都可以让机器人帮你完成.想必此刻 ...
- 一文读懂字符编码ASCII、Unicode与UTF-8
先说一下,为什么写这篇文章? 最近在写一个Http协议栈当涉及CRLF控制字符写入时,发现自己对CRLF与\r\n的关系不太了解,因此决定详细学习一下:查阅资料的同时,又遇到UTF-8与ASCII编码 ...
- Spring Cloud 学习笔记(周阳)
参考博客:https://blog.csdn.net/u011863024/article/details/114298270 内容:netflix,alibaba
- 【读书笔记】格子路径计数LatticePathEnumeration 学一半的笔记
流水账流水账这篇什么都不是 目录 方法 10.2 Lattice paths without restrictions 无限制格子路径 2维的例子,从(a,b)到(c,d),允许(0,1)和(1,0) ...
- 玩转SpringBoot原理:掌握核心技术,成为高级开发者
本文通过编写一个自定义starter来学习springboot的底层原理,帮助我们更好的使用springboot集成第三方插件 步骤一:创建项目 步骤二:添加依赖 步骤三:创建自动配置类 步骤四:创建 ...
- Java面试——JVM知识
一.什么情况下会发生栈内存溢出 [1]线程请求的栈深度大于虚拟机所允许的深度,将抛出 StackOverflowError 异常.递归的调用一个简单的方法,不断累积就会抛出 StackOverflow ...
- RFM客户分类模型的应用——R语言
RFM模型是衡量客户价值和客户创造利益能力的重要工具和手段.在众多的客户关系管理(CRM)的分析模式中,RFM模型是被广泛提到的.该机械模型通过一个客户的近期购买行为.购买的总体频率以及花了多少钱3项 ...