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 <------- ...
随机推荐
- shortcuts
关闭选项卡 Ctrl+W 关闭当前窗口 alt + F4 alt + 空格 + c alt + 空格 + n 最小化窗口 alt + 空格 + x 最大化窗口 ALT+F4 关闭当前应用程序 ctrl ...
- java相关部分配置
一.mybatis逆向工程 ① generator.properties jdbc.driverLocation=D:/testDir/Maven/repository_g/mysql/mysql-c ...
- RF射频的定义和原理
转自:http://www.saiyuan.net/portal/article/index/id/119/cid/28.html RF射频的定义和原理 定义 简称RF射频就是射频电流,它是一种高频交 ...
- 使用npm包API Promise化
- Js:当前日期格式化与比较大小
//日期格式转换 getCurrentTime() { var date = new Date();//当前时间 var year = date.getFullYear() //返回指定日期的年份 v ...
- 【Beat】Scrum Meeting 4
时间:2021年6月29日 1.各个成员今日完成的任务以及贡献小时数 姓名 今日完成任务 贡献小时数 鑫 继续进行bug的修改 4 荣娟 继续进行bug的修改 4 亚楠 继续进行bug的修改 4 桂婷 ...
- 【python】yaml文件的读写
[python]yaml文件的读写 冰冷的希望 2020-10-22 18:31:47 442 收藏 1分类专栏: python 文章标签: python yaml版权 python专栏收录该内容67 ...
- Flink双流消费kafka合并数据,并包含滑动窗口、算子、输出到MySQL的示例
Java示例 import org.apache.flink.api.common.functions.MapFunction; import org.apache.flink.api.java.fu ...
- K8S 性能优化 - OS sysctl 调优
前言 K8S 性能优化系列文章,本文为第一篇:OS sysctl 性能优化参数最佳实践. 参数一览 sysctl 调优参数一览 # Kubernetes Settings vm.max_map_cou ...
- Spring--AOP通知获取数据
AOP通知获取数据 获取参数 用before进行举例: 用around进行举例: 需要注意的是,Around的话,还可以处理一些之前发生异常的数据,直接在这里进行修改也是支持的: 获取返回值 环绕已经 ...