//顾名思义,就是用来生成sdp描述信息的。
char* ServerMediaSession::generateSDPDescription() {
//获取本地IP地址
AddressString ipAddressStr(ourIPAddress(envir()));
unsigned ipAddressStrSize = strlen(ipAddressStr.val()); //不会执行到ssm里面,还不知道SSM是什么
// For a SSM sessions, we need a "a=source-filter: incl ..." line also:
char* sourceFilterLine;
if (fIsSSM) {
char const* const sourceFilterFmt =
"a=source-filter: incl IN IP4 * %s\r\n"
"a=rtcp-unicast: reflection\r\n";
unsigned const sourceFilterFmtSize = strlen(sourceFilterFmt) + ipAddressStrSize + ; sourceFilterLine = new char[sourceFilterFmtSize];
sprintf(sourceFilterLine, sourceFilterFmt, ipAddressStr.val());
} else {
sourceFilterLine = strDup("");
} char* rangeLine = NULL; // for now
char* sdp = NULL; // for now /*
* 有2种级别的sdp信息,一个叫子媒体级别的sdp,一个叫会话级别的sdp。
* 先计算保存sdp可能需要的内存空间大小,然后再格式化生成sdp字符串放入内存中保存起来。
*/
do {
// Count the lengths of each subsession's media-level SDP lines.
// (We do this first, because the call to "subsession->sdpLines()"
// causes correct subsession 'duration()'s to be calculated later.)
unsigned sdpLength = ;
ServerMediaSubsession* subsession;
for (subsession = fSubsessionsHead; subsession != NULL;
subsession = subsession->fNext) {
//遍历子媒体会话,获取各个子会话的sdp描述信息长度。
char const* sdpLines = subsession->sdpLines();
if (sdpLines == NULL) continue; // the media's not available
sdpLength += strlen(sdpLines);
}
if (sdpLength == ) break; // the session has no usable subsessions //获取媒体时长的sdp描述
// Unless subsessions have differing durations, we also have a "a=range:" line:
float dur = duration();
if (dur == 0.0) {
rangeLine = strDup("a=range:npt=0-\r\n");
} else if (dur > 0.0) {
char buf[];
sprintf(buf, "a=range:npt=0-%.3f\r\n", dur);
rangeLine = strDup(buf);
} else { // subsessions have differing durations, so "a=range:" lines go there
rangeLine = strDup("");
} //根会话级别的sdp固定格式
char const* const sdpPrefixFmt =
"v=0\r\n"
"o=- %ld%06ld %d IN IP4 %s\r\n"
"s=%s\r\n"
"i=%s\r\n"
"t=0 0\r\n"
"a=tool:%s%s\r\n"
"a=type:broadcast\r\n"
"a=control:*\r\n"
"%s"
"%s"
"a=x-qt-text-nam:%s\r\n"
"a=x-qt-text-inf:%s\r\n"
"%s"; //计算需要多大的内存空间来存储生成的完整sdp信息。
sdpLength += strlen(sdpPrefixFmt)
+ + + + ipAddressStrSize
+ strlen(fDescriptionSDPString)
+ strlen(fInfoSDPString)
+ strlen(libNameStr) + strlen(libVersionStr)
+ strlen(sourceFilterLine)
+ strlen(rangeLine)
+ strlen(fDescriptionSDPString)
+ strlen(fInfoSDPString)
+ strlen(fMiscSDPLines);
//适度地增加一点内存空间,防止后面子会话级别sdp和上面计算的长度不同。
sdpLength += ; // in case the length of the "subsession->sdpLines()" calls below change
//申请一段内存空间,用来存放后面生成的整个sdp字符串。
sdp = new char[sdpLength];
if (sdp == NULL) break; /*
* 完整的sdp的组成格式是:一个根会话sdp + 多个子媒体sdp。
*
*/ //格式化生成根媒体会话sdp
// Generate the SDP prefix (session-level lines):
snprintf(sdp, sdpLength, sdpPrefixFmt,
fCreationTime.tv_sec, fCreationTime.tv_usec, // o= <session id>
, // o= <version> // (needs to change if params are modified)
ipAddressStr.val(), // o= <address>
fDescriptionSDPString, // s= <description>
fInfoSDPString, // i= <info>
libNameStr, libVersionStr, // a=tool:
sourceFilterLine, // a=source-filter: incl (if a SSM session)
rangeLine, // a=range: line
fDescriptionSDPString, // a=x-qt-text-nam: line
fInfoSDPString, // a=x-qt-text-inf: line
fMiscSDPLines); // miscellaneous session SDP lines (if any) //接着,把全部的子媒体级别sdp拼接起来,放到跟会话级别sdp的后面。
// Then, add the (media-level) lines for each subsession:
char* mediaSDP = sdp;
for (subsession = fSubsessionsHead; subsession != NULL;
subsession = subsession->fNext) {
unsigned mediaSDPLength = strlen(mediaSDP);
mediaSDP += mediaSDPLength;
sdpLength -= mediaSDPLength;
if (sdpLength <= ) break; // the SDP has somehow become too long //获取子媒体sdp
char const* sdpLines = subsession->sdpLines();
if (sdpLines != NULL) snprintf(mediaSDP, sdpLength, "%s", sdpLines);
}
} while (); delete[] rangeLine; delete[] sourceFilterLine;
//返回完整sdp信息。
return sdp;
}

完。

ServerMediaSession::generateSDPDescription分析的更多相关文章

  1. rtsp 学习之路一

    http://baijiahao.baidu.com/s?id=1587715130853990653&wfr=spider&for=pc https://www.cnblogs.co ...

  2. (转)live555学习笔记9-h264 RTP传输详解(1)

    九 h264 RTP传输详解(1) 前几章对Server端的介绍中有个比较重要的问题没有仔细探究:如何打开文件并获得其SDP信息.我们就从这里入手吧. 当RTSPServer收到对某个媒体的DESCR ...

  3. 【视频开发】RTSP SERVER(基于live555)详细设计

    /* *本文基于LIVE555的嵌入式的RTSP流媒体服务器一个设计文档,个中细节现剖于此,有需者可参考指正,同时也方便后期自己查阅.(本版本是基于2011年的live555) 作者:llf_17@q ...

  4. (转)基于live555的流媒体代理转发服务器

    对于并发量并不大而且对性能要求不是很高的流媒体传输模块,live555还是很好的选择,下面说一下我所实现的流媒体代理服务器(目前只能实现对H264单视频的转发)代理转发主要 对于并发量并不大而且对性能 ...

  5. Live555 分析(一):类介绍

    从程序的结构来看,live项目包括了四个基本库.程序入口类(在mediaServer中)和一些测试代码(在testProgs中). 四个基本静态库是UsageEnvironment.BasicUsag ...

  6. Live555 分析(二):服务端

    live555支持单播和组播,我们先分析单播的流媒体服务端,后面分析组播的流媒体服务端. 一.单播的流媒体服务端: // Create the RTSP server: RTSPServer* rts ...

  7. live555 源代码简单分析1:主程序

    live555是使用十分广泛的开源流媒体服务器,之前也看过其他人写的live555的学习笔记,在这里自己简单总结下. live555源代码有以下几个明显的特点: 1.头文件是.hh后缀的,但没觉得和. ...

  8. (转)Live555中RTSPClient分析

    有RTSPServer,当然就要有RTSPClient. 如果按照Server端的架构,想一下Client端各部分的组成可能是这样:因为要连接RTSP server,所以RTSPClient要有TCP ...

  9. 【VS开发】【Live555-rtsp】RTSP服务器实例live555源代码分析

    原文地址:RTSP服务器实例live555源代码分析作者:mozheer 1. RTSP连接的建立过程 RTSPServer类用于构建一个RTSP服务器,该类同时在其内部定义了一个RTSPClient ...

随机推荐

  1. MySQL (ZIP Archive) 下载及安装及卸载

    下载地址官网: http://www.mysql.com/downloads/ MySQL Enterprise Edition 需要注册账户并且与Oracle公司购买 可以直接下载 MySQL Co ...

  2. Mac OS—苹果搭建Android开发环境

    如何在MAC OS X 安装Android SDK 我以往用的开发环境都是以MAC OS安装VMware来跑不同的Windows OS,目前慢慢的将所要开发的项目由以往的传统的Wintel转移到Mob ...

  3. javascript设计模式学习之十五——装饰者模式

    一.装饰者模式定义 装饰者模式可以动态地给某个对象添加一些额外的职责,而不会影响从这个类中派生的其他对象.这种为对象动态添加职责的方式就称为装饰者模式.装饰者对象和它所装饰的对象拥有一致的接口,对于用 ...

  4. UIKit结构图

  5. Hint

    select  /*+  first_rows(20)  */  *  from  t  where  id<20 --分页 select  /*+  all_rows  */  *  from ...

  6. 使用ajax请求,模态框调用并更改密码

    前端页面 <a href="javascript:void(0);" onclick="changPassword()"> <i class= ...

  7. 怎么设置task的最大线程数

    //-------------------------------------------------------------------------- // // Copyright (c) Mic ...

  8. 在Adobe AIR/AS 程序中 如何设置目录

    首先所有目录都以 "File:///"开头,无论Mac或者Windows 后面的路径 Windows: E:/WorkGround/Txt.txt  --> "Fi ...

  9. JetBrains公司介绍(Java、Python、PHP、Ruby、前端和代码测试与重构的IDE)

    JetBrains JetBrains是一家捷克的软件开发公司,该公司位于捷克的布拉格,并在俄国的圣彼得堡及美国麻州波士顿都设有办公室,该公司最为人所熟知的产品是Java编程语言开发撰写时所用的集成开 ...

  10. Python和Ruby开发中源文件中文注释乱码的解决方法(Eclipse和Aptana Studio3均适用)

    Eclipse的设置(Aptana Studio3与Eclipse基本完全相同,此处略) window->preferences->general->editors->text ...