zoukankan      html  css  js  c++  java
  • 用live555开发应用程序(二)

    转自:http://www.rosoo.net/a/201210/16304.html,尊重原创!

    一个简单的RTSP客户端程序

    在另一个文章里,给出了这个简单的客户端的程序的代码,可以通过修改Makefile来裁剪liveMedia,使得这个客户端最小化。此客户端已经正常运行。

    首先是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对象

                   TaskScheduler* scheduler = BasicTaskScheduler::createNew();

    2.            创建BisicUsageEnvironment对象

                   UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler); 

    3.            分析argv参数,(最简单的用法是:openRTSP rtsp://172.16.24.240/mpeg4video.mp4)以便在下面设置一些相关参数

                   if (argc < 2) {     usage(*env, argv[0]);      return 1;        }

    4.            创建RTSPClient对象

                   RTSPClient* rtspClient = ourRTSPClient::createNew(env, rtspURL, RTSP_CLIENT_VERBOSITY_LEVEL, progName);封装在openURL()中

    5.            由RTSPClient对象向服务器发送OPTION消息并接受回应

    6.            产生SDPDescription字符串(由RTSPClient对象向服务器发送DESCRIBE消息并接受回应,根据回应的信息产生SDPDescription字符串,其中包括视音频数据的协议和解码器类型)

                   rtspClient->sendDescribeCommand(continueAfterDESCRIBE);         

    7.            创建MediaSession对象(根据SDPDescription在MediaSession中创建和初始化MediaSubSession子会话对象)

    8.            while循环中配置所有子会话对象(为每个子会话创建RTPSource和RTCPInstance对象,并创建两个GroupSock对象,分别对应 RTPSource和RTCPInstance对象,把在每个GroupSock对象中创建的socket描述符置入 BasicTaskScheduler::fReadSet中,RTPSource对象的创建的依据是SDPDescription,例如对于MPEG4 文件来说,视音频RTPSource分别对应MPEG4ESVideoRTPSource和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消息给客户端,客户端接收到该消息后释放资源,程序退出。

    }
  • 相关阅读:
    Tensorflow之MNIST机器学习入门
    MongoDB学习第七篇 --- sql和mongodb对比
    MongoDB学习第六篇 --- Delete操作
    MongoDB学习第五篇 --- Update操作
    MongoDB学习第四篇 --- Query操作
    MongoDB学习第三篇 --- Insert操作
    MongoDB学习第二篇 --- Mac下通过 Shell 执行 mongo 命令
    MongoDB学习第一篇 --- Mac下使用HomeBrew安装MongoDB
    python连接sql server数据库实现增删改查
    转。webapp开发小tips
  • 原文地址:https://www.cnblogs.com/wyqfighting/p/2875102.html
Copyright © 2011-2022 走看看