ServerMediaSession::generateSDPDescription分析
//顾名思义,就是用来生成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分析的更多相关文章
- rtsp 学习之路一
http://baijiahao.baidu.com/s?id=1587715130853990653&wfr=spider&for=pc https://www.cnblogs.co ...
- (转)live555学习笔记9-h264 RTP传输详解(1)
九 h264 RTP传输详解(1) 前几章对Server端的介绍中有个比较重要的问题没有仔细探究:如何打开文件并获得其SDP信息.我们就从这里入手吧. 当RTSPServer收到对某个媒体的DESCR ...
- 【视频开发】RTSP SERVER(基于live555)详细设计
/* *本文基于LIVE555的嵌入式的RTSP流媒体服务器一个设计文档,个中细节现剖于此,有需者可参考指正,同时也方便后期自己查阅.(本版本是基于2011年的live555) 作者:llf_17@q ...
- (转)基于live555的流媒体代理转发服务器
对于并发量并不大而且对性能要求不是很高的流媒体传输模块,live555还是很好的选择,下面说一下我所实现的流媒体代理服务器(目前只能实现对H264单视频的转发)代理转发主要 对于并发量并不大而且对性能 ...
- Live555 分析(一):类介绍
从程序的结构来看,live项目包括了四个基本库.程序入口类(在mediaServer中)和一些测试代码(在testProgs中). 四个基本静态库是UsageEnvironment.BasicUsag ...
- Live555 分析(二):服务端
live555支持单播和组播,我们先分析单播的流媒体服务端,后面分析组播的流媒体服务端. 一.单播的流媒体服务端: // Create the RTSP server: RTSPServer* rts ...
- live555 源代码简单分析1:主程序
live555是使用十分广泛的开源流媒体服务器,之前也看过其他人写的live555的学习笔记,在这里自己简单总结下. live555源代码有以下几个明显的特点: 1.头文件是.hh后缀的,但没觉得和. ...
- (转)Live555中RTSPClient分析
有RTSPServer,当然就要有RTSPClient. 如果按照Server端的架构,想一下Client端各部分的组成可能是这样:因为要连接RTSP server,所以RTSPClient要有TCP ...
- 【VS开发】【Live555-rtsp】RTSP服务器实例live555源代码分析
原文地址:RTSP服务器实例live555源代码分析作者:mozheer 1. RTSP连接的建立过程 RTSPServer类用于构建一个RTSP服务器,该类同时在其内部定义了一个RTSPClient ...
随机推荐
- msvc库没有安装包,编译选项选择 代码生成 MT【多线程】,C#调用
参考提过的一个问题,封装VC++动态链接库,C#调用,并将C#程序打包为exe安装包. 感谢大神.
- canvas的代码封装
(function(window,document){ var cs2d = function(selector,options){ return new cs2d.fn.init(selector, ...
- Visual Studio Debugger AutoExp.dat & Visualization Framework
bing.com搜索: autoexp.dat 参考资料: AutoExp.dat http://www.virtualdub.org/blog/pivot/entry.php?id=120 http ...
- Java Collections的排序之二
package test.list; import java.util.ArrayList; import java.util.Collections; import java.util.HashSe ...
- iOS - (简单平移动画/弹出View的使用)
在iOS 开发中,使用平移动画的频率越来越高,给人的感觉就是很炫酷很流畅,起到增强用户体验的作用.在APP开发中实现动画效果有很多种方式,但我目前是使用较多的是平移动画,顺便也在此做一些小小的总结,大 ...
- 有关于break,continue,return的区别和代码分析
今天,用代码和结果直接解释break,continue,return的区别 1.break代码 public static void breakTest() { //break的讲解 for(int ...
- PostgreSQL 一主两备节点(两备节点为同步节点)故障恢复
PostgreSQL 同步复制及故障恢复 10.2.208.10:node1:master 10.2.208.11:node2:standby1 同步 10.2.208.12:node3:stand ...
- PostgreSQL configuration file postgresql.conf recommanded settings and how it works
1 Set max_connections to three times the number of processor cores on the server. Include vir ...
- 初始化 Gradle 工程目录(转自: 隔叶黄莺 Unmi Blog)
最近重新在 Eclipse 中打开旧的 Maven 项目,总有些什么错误,备受折磨.期间试手了 Ant+Ivy, 现今试用了下 Gradle,感觉不错,它应该才是我真想要的,Maven 差不多该扔到一 ...
- 强连通(hdu4635)最多增加几条单向边后满足最终的图形不是强连通
Strongly connected Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...