live555--服务器,客户端(转载)
来源:互联网 发布:社会活动家知乎 编辑:程序博客网 时间:2024/06/05 08:01
本文转自http://blog.csdn.net/gavinr/article/details/7050797
原文:http://blog.csdn.net/evsqiezi/article/details/7895715
服务器
用live555中的库写了一个最简单的RTSPServer程序,仅用于学习目的。从下例的代码中,可以清析的明白RTSPServer的函数调用流程。
- static ServerMediaSession* createNewSMS(UsageEnvironment& env, char const* fileName);
- int main()
- {
- TaskScheduler* scheduler;
- UsageEnvironment* env ;
- RTSPServer* rtspServer;
- ServerMediaSession* sms;
- //创建任务调用器
- scheduler = BasicTaskScheduler::createNew();
- //创建交互环境
- env = BasicUsageEnvironment::createNew(*scheduler);
- //创建RTSP服务器
- rtspServer = RTSPServer::createNew(*env,554); //使用554端口
- if(rtspServer == NULL)
- {
- rtspServer = RTSPServer::createNew(*env,8554); //554端口被占用,就使用8554端口
- }
- //打印服务器地址
- *env << "Play streams from this server using the URL\n\t"
- << rtspServer->rtspURLPrefix() << "<filename>.\n";
- //创建session
- sms = createNewSMS(*env, "test.mpg");
- rtspServer->addServerMediaSession(sms);
- //添加其它文件对应的session...
- //进行事件循环
- env->taskScheduler().doEventLoop(); // does not return
- return 0;
- }
- static ServerMediaSession* createNewSMS(UsageEnvironment& env, char const* fileName)
- {
- char const* extension = strrchr(fileName, '.');
- ServerMediaSession* sms = NULL;
- Boolean reuseSource = False; //不重用source
- sms = ServerMediaSession::createNew(env, fileName); //创建一个session
- //
- //在session中添加subssesion
- //
- if(strcmp(extension, ".aac") == 0)
- {
- sms->addSubsession(ADTSAudioFileServerMediaSubsession::createNew(env, fileName, reuseSource));
- }
- else if(strcmp(extension, ".264") == 0)
- {
- sms->addSubsession(H264VideoFileServerMediaSubsession::createNew(env, fileName, reuseSource));
- }
- else if(strcmp(extension, ".mpg") == 0)
- {
- MPEG1or2FileServerDemux* demux
- = MPEG1or2FileServerDemux::createNew(env, fileName, reuseSource);
- sms->addSubsession(demux->newVideoServerMediaSubsession());
- sms->addSubsession(demux->newAudioServerMediaSubsession());
- }
- //添加其它媒体格式支持...
- return sms;
- }
客户端
首先是OPTION
然后是DESCRIBE
建立Media Session,调用的函数是 MediaSession::createNew,在文件liveMedia/MediaSession.cpp中实现。为这个Media Session建立RTPSource,这是通过调用 MediaSubsession::initiate来实现的的,这个方法在liveMedia/MediaSession.cpp中实现。
在然后是SETUP
最后是PLAY
rtp数据的句柄:MultiFramedRTPSource::networkReadHandler 在liveMedia/MultiFramedRTPSource.cpp中
rtcp数据处理的句柄:RTCPInstance::incomingReportHandler 在liveMedia/RTCP.cpp中
rtp数据处理的句柄的设置:MultiFramedRTPSource: oGetNextFrame 在liveMedia/MultiFramedRTPSource.cpp中, 被FileSink::continuePlaying调用在FileSink.cpp中.
rtcp数据处理的句柄设置fRTCPInstance = RTCPInstance::createNew 在/liveMedia/MediaSession.cpp中调用,
createNew调用了构造函数RTCPInstance::RTCPInstance,这个构造函数有如下调用
TaskScheduler::BackgroundHandlerProc* handler = (TaskScheduler::BackgroundHandlerProc*)&incomingReportHandler;
通过分析live库提供的例子程序OpenRTSP,可以清晰地了解客户端接收来自网络上媒体数据的过程。注意,RTP协议和RTCP协议接收的数据分别是视音频数据和发送/接收状况的相关信息,其中,RTP协议只负责接收数据,而RTCP协议除了接收服务器的消息之外,还要向服务器反馈。
A. main函数流程
main(int argc,char *argv[])
{
1. 创建BasicTaskScheduler对象
2. 创建BisicUsageEnvironment对象
3. 分析argv参数,(最简单的用法是:openRTSP rtsp://172.16.24.240/mpeg4video.mp4)以便在下面设置一些相关参数
4. 创建RTSPClient对象
5. 由RTSPClient对象向服务器发送OPTION消息并接受回应
6. 产生SDPDescription字符串(由RTSPClient对象向服务器发送DESCRIBE消息并接受回应,根据回应的信息产生SDPDescription字符串,其中包括视音频数据的协议和解码器类型)
7. 创建MediaSession对象(根据SDPDescription在MediaSession中创建和初始化MediaSubSession子会话对象)
8. while循环中配置所有子会话对象(为每个子会话创建RTPSource和RTCPInstance对象,并创建两个GroupSock对象,分别对应 RTPSource和RTCPInstance对象,把在每个GroupSock对象中创建的socket描述符置入 BasicTaskScheduler::fReadSet中,RTPSource对象的创建的依据是SDPDescription,例如对于MPEG4 文件来说,视音频RTPSource分别对应MPEG4ESVideoTRPSource和MPEG4GenericRTPSource对象。 RTCPInstance对象在构造函数中完成将Socket描述符、处理接收RTCP数据的函数 (RTCPInstance::incomingReportHandler)以及RTCPInstance本身三者绑定在一个 HandlerDescriptor对象中,并置入BasicTaskScheduler::fReadHandler中。完成绑定后会向服务器发送一条消息。)
9. 由RTSPClient对象向服务器发送SETUP消息并接受回应。
10. while循环中为每个子会话创建接收器(FileSink对象),在FileSink对象中根据子会话的codec等属性缺省产生记录视音频数据的文件名,视音频文件名分别为:video-MP4V-ES-1和audio-MPEG4-GENERIC-2,无后缀名
11. while循环中为每个子会话的视音频数据装配相应的接收函数,将每个子会话中的RTPSource中的GroupSock对象中的SOCKET描述符,置入BasicTaskScheduler::fReadSet中,并将描述符、处理接收RTP数据的函数 (MultiFramedRTPSource::networkReadHandler)以及RTPSource本身三者绑定在一个 HandlerDescriptor对象中,并置入BasicTaskScheduler::fReadHandler中,并将FileSink的缓冲区和包含写入文件操作的一个函数指针配置给RTPSource对象,这个缓冲区将会在networkReadHandler中接收来自网络的视音频数据(分析和去掉RTP包头的工作由RTPSource完成),而这个函数指针在networkReadHandler中被调用以完成将缓冲区中的数据写入文件。
12. 由RTSPClient对象向服务器发送PLAY消息并接受回应。
13. 进入while循环,调用BasicTaskScheduler::SingleStep()函数接受数据,直到服务器发送TREADOWN消息给客户端,客户端接收到该消息后释放资源,程序退出。
- live555--服务器,客户端(转载)
- live555的一点bug修改(客户端和服务器)
- live555客户端
- Live555流媒体服务器,FFmpeg客户端接收并切片ts流
- live555二次开发经验总结:RTSPClient客户端与RTSPServer服务器
- live555二次开发经验总结:RTSPClient客户端与RTSPServer服务器
- live555的安装 RTSP点播消息流程实例(客户端:VLC, RTSP服务器:LIVE555 Media Server)
- rtsp客户端 & ffmpeg解码(基于live555)
- 【转载】live555学习 --H264数据处理(2)
- 【转载】live555学习 --H264数据处理(1)
- 【转载】live555学习 --H264数据处理(3)
- live555客户端OpenRtsp流程
- live555客户端ffmpeg
- live555 客户端的实现
- live555学习 转载 + 原创
- RTSP点播消息流程实例(客户端:VLC, RTSP服务器:LIVE555 Media Server)
- RTSP点播消息流程实例(客户端:VLC, RTSP服务器:LIVE555 Media Server)
- RTSP点播消息流程实例(客户端:VLC, RTSP服务器:LIVE555 Media Server)
- HTTP 状态代码含义集合
- USB请求块(URB)——框架及机制
- 我的2012和2013,吼吼
- iPhone蓝牙编程之实现语音聊天 .
- VS2010rdlc报表—根据查询条件产生报表
- live555--服务器,客户端(转载)
- 二〇一三年五月十五日
- Win8传感器—加速度计、陀螺仪、指南针
- 设计模式 - 装饰模式、原型模式、模板模式、享元模式
- POJ 3084 Panic Room (最小割)
- capwap学习笔记——初识capwap(一)
- PLL和DLL:都是锁相环,区别在哪里?
- java.util.Date和java.sql.Date的区别
- iOS CoreAnimation