2024年4月21日发(作者:)
流媒体分析
MEDIASTREAMER2分析研究
Ver 0.2
文档变更记录
日期
第 1 页 2022-4-27
版本
作者
改动
流媒体分析
1. 目的 ................................................................................................................................................................. 4
2. 总体架构 ......................................................................................................................................................... 4
2.1. 概述 ..................................................................................................................................................... 4
2.2. 总体描述 ............................................................................................................................................. 4
2.2.1. 业务流程描述 .......................................................................................................................... 4
2.2.2. 总体功能模块描述 .................................................................................................................. 5
2.3. 功能描述 ............................................................................................................................................. 6
2.3.1. 注册FILTER ........................................................................................................................... 6
2.3.2. FILTER Link/执行 ................................................................................................................... 6
2.3.3. 循环执行 FILTER .................................................................................................................. 6
2.3.4. FILTER UNILIK ...................................................................................................................... 6
2.3.5. RTP 发送/接收FILTER ......................................................................................................... 6
2.3.6. 音频编解码FILTER ............................................................................................................... 7
2.3.7. 视频编解码FILTER ............................................................................................................... 7
2.3.8. 音视频播放FILTER ............................................................................................................... 7
2.3.9. 音视频捕获FILTER ............................................................................................................... 7
2.3.10. ORTP的功能描述 ................................................................................................................. 7
2.4. 程序运行逻辑 ..................................................................................................................................... 8
2.4.1. MEDIASTREAMER2 ............................................................................................................. 8
2.4.2. 10
3. 编译流程 ....................................................................................................................................................... 11
3.1. 平台描述 ........................................................................................................................................... 11
3.2. 依赖环境 ........................................................................................................................................... 11
3.3. 编译设置 ........................................................................................................................................... 12
4. 二次扩展 ....................................................................................................................................................... 12
4.1. 功能修改 ........................................................................................................................................... 12
4.2. 编/解码的扩展 .................................................................................................................................. 12
4.2.1. ORTP扩展 ............................................................................................................................. 12
4.2.2. MEDIASTREAMER2扩展 .................................................................................................. 13
4.2.3. 调用 ....................................................................................................................................... 15
4.3. 插件的扩展 ....................................................................................................................................... 15
4.3.1. ORTP中的配置 ..................................................................................................................... 15
4.3.2. MS中的配置 ......................................................................................................................... 15
4.3.3. 遵循的函数接口标准 ............................................................................................................ 15
4.3.4. 调用 ....................................................................................................................................... 15
5. 数据结构 ....................................................................................................................................................... 16
5.1. 框架数据结构 ................................................................................................................................... 16
5.1.1. 函数指针定义: .................................................................................................................... 16
5.1.2. MSFilterMethod ..................................................................................................................... 16
5.1.3. . 16
5.1.4. MSFilterDesc ......................................................................................................................... 17
5.1.5. MSFilter ................................................................................................................................. 17
5.1.6. MSConnectionPoint ............................................................................................................... 18
5.2. 传输数据结构 ................................................................................................................................... 18
第 2 页 2022-4-27
流媒体分析
6. API描述 ........................................................................................................................................................ 18
6.1. 传输API ............................................................................................................................................ 18
6.2. 语音控制API .................................................................................................................................... 19
6.3. 视频控制API .................................................................................................................................... 19
6.4. 编/解码API ....................................................................................................................................... 19
6.5. FILTER管理API .............................................................................................................................. 19
7. MS与SIP集成 ............................................................................................................................................. 21
8. MS提供给界面控制的函数 ......................................................................................................................... 21
9. MS中其它描述 ............................................................................................................................................. 22
第 3 页 2022-4-27
流媒体分析
1. 目的
本次分析研究VOIP中流媒体部分,是为将来在企业通讯客户端中实现软电话来呼叫外部电话;外部
电话通过IPPBX上的语音提示来呼叫本地软电话;软电话和普通电话互通;不同办公地点之间音视频传
输;语音邮件等。
在分析开源代码的基础上,扩展流媒体在传输过程中的编码和优化流媒体通讯过程中的语音,视频
质量。
为满足上述目的,我们采用分析LINPHONE开源代码中流媒体部分,经过分析发现该流媒体部分在功
能上完全能满足上述目的。该框架比较小且非常灵活,完全可以通过二次开发来优化传输过程中的流媒
体质量。
2. 总体架构
2.1. 概述
LINPHONE中流媒体处理分为2个部分MEDIASTREAMER2和ORTP,前者负责媒体流的处理后者负责流媒
体如何安全可靠的传输.
关于MEDIASTREAMER2,以下简称MS。
MS和ORTP为二个项目文件,由于MS利用ORTP作为传输部分使用,因此在下面描述中认为ORTP是
其中的一部分功能。
ORTP实现了RTP协议,提供良好的API访问功能.多种RTP格式支持;发送接收的实时调度;单线程
支持多路媒体流;自适应的缓冲区算法;实现了RTCP。目前我们采用的是ORTP 0.16.1的最新版本
.
2.2. 总体描述
2.2.1. 业务流程描述
同很多软终端一样,在MS中实现的业务流程基本一样。以下图描述了一个单向的处理。MS在传输过
程中用一个全双工的session来传送视频或者音频,不管是本机还是远端主机,运行的都是同一个程序,
一次只能选择一种payload。
第 4 页 2022-4-27
流媒体分析
A端
采集流媒体对流媒体编码发送流媒体数据
流媒体网关
播放流媒体对流媒体解码接收流媒体数据
以上为一完整的VOIP软终端的实现流程,采集语音和视频的信息,经过一定的编码,通过RTP协议
传输流媒体数据到网关(IPPBX),流媒体网关可能会对数据进行处理,也可能是直接连接流媒体,这时
候对方可以接收流媒体的数据开始播放。这样就实现连单方的通话,把整个流程反过来就实现了一个完
整的流媒体传输通道。
2.2.2. 总体功能模块描述
MS的总体逻辑关系非常简单,它利用函数指针将一系列的FILTER组合起来,通过一个线程来调度这
些FILTER上的函数指针。
音频捕获FILTER视频捕获FILTER音频编码FILTER视频编码FILTERRTP 发送FILTER
注册FILTERFILTER Link/执行
RTP 接收FILTER音频解码FILTER
以上为整个MS的功能模块图,可以看出MS框架除了具有维护FILTER功能之外处理事情非常少,它
利用函数指针来管理这些FILTER,而这些FILTER之间的逻辑关系则通过系统启动的时候配置加载,也就
是说如果实现一个电话软终端,我们可以根据SIP协议和对方协商的SDP配置包来决定我们来加载语音
或者是视频流。
B端
Mediastream2媒体流框架
循环执行 FILTER
视频解码FILTER
视频播放FILTER
FILTER UNILIK
音频播放FILTER
第 5 页 2022-4-27
流媒体分析
2.3. 功能描述
根据总体功能模块描述分以下几个小的功能:
2.3.1. 注册FILTER
注册分为二部分,一部分为RTP协议中的注册,由于ORTP基本上实现了RTP协议上的所有规范,在
ORTP部分先要注册与协议相关的信息,而在MS部分则主要注册FILTER的ID;FILTER的函数指针;以及
该函数指针和外部的API的调用关系。这部分要涉及到写程序,实现各种FILTER和外部函数之间的一一
对应关系。
2.3.2. FILTER Link/执行
由于有太多的FILTER,我们无法确定所有用户之间通讯都采用一种编码的方式,而且FILTER之间的
逻辑关系也无法确定,因此需要一个配置能决定我们采用的编码,FILTER之间的关系.基本上每个FILTER
都具备一个入一个出的属性,但是在采集和播放的时候FILTER只有一个属性。
在FILTER LINK之前基本上决定了流媒体的类型,LINK之后我们又知道了每个FILTER之间的关系。
但是我们在采集媒体信息的时候要设置声音效果,质量,回音处理等。所以FILTER还要提供一次性的方
法来配置这些属性。在FILTER LINK之前通过函数指针来调用FILTER的附加函数指针,该调用方式一般
是一次行为。非FILTER的标准函数指针。
2.3.3. 循环执行 FILTER
这个功能非常重要,在上面定义了FILTER,定义了FILTER的先后逻辑关系.现在要通过一个线程来持
续不断的处理这些逻辑.由于FILTER之间的关系通过一个非循环的双链表来关联. 这个过程并非连续循
环执行,循环过程只是从队列头到队列尾的一个过程. 语音流程有2个队列头,一个以采集为起点到发送
为终点;一个以接收为起点到播放为终点.而视频则不这样。该功能将在下面详细描述。
2.3.4. FILTER UNILIK
取消每个FILTER之间的关系。
2.3.5. RTP 发送/接收FILTER
MS通过对ORTP的封装,在调用的时候认为ORTP传输部分的FILTER,按照实现方式来说,我们可以
采用其它的RTP传输库来做FILTER。通过ORTP库中集成的RTP库可以猜测,该功能是可以实现的。
第 6 页 2022-4-27
流媒体分析
2.3.6. 音频编解码FILTER
音频的编码和解码一般为一对,在MS中支持的有g711u, g711a, speex 和gsm等编码,目前已经加入
了G729A.,也能够通过动态的办法加载新的编码.
2.3.7. 视频编解码FILTER
视频的FILTER目前支持H263-1998, MP4V-ES, theora.同时也可以通过插件的方式来添加H264的编码,
目前的库是X264。
2.3.8. 音视频播放FILTER
这个FILTER只是通过WINDOWS API来从设备上读数据和写数据到设备上.
2.3.9. 音视频捕获FILTER
2.3.10.
ORTP的功能描述
多种RTP格式支持
ortp有一个RtpProfile的全局变量,该变量在ortp初始化的时候赋值,该变量中有一个
PayloadType的数组,每个PayloadType对应一种媒体流,PayloadType中包含了媒体流的特性,包
括名称,采样率,声音位数,静音格式,占用带宽等。这些定义都在avprofile.c中。其中的几个
参数中,采样率用的比较多,主要用来计算实时性.。
发送接收的实时调度。
发送和接收主要是两个函数rtp_session_send_with_ts和rtp_session_recv_with_ts。以
rtp_session_recv_with_ts为例:内部接收数据使用的是rtp_session_recvm_with_ts,首先,会
接收所有scoket上的数据,然后将rtp包存放在一个队列之中,一系列处理之后,有一个
pthread_mutex_lock的线程锁,将线程锁住。此时,由rtp_scheduler_schedule线程进行调度(该
线程在协议栈初始化)时创建。rtp_scheduler_schedule会遍历所有的media session(媒体流),
然后判断其中的timestamp(时间戳),如果计算的时间到达,则让rtp_session_recvm_with_ts继
续处理。
时间戳的算法是以第一个打到的rtp数据包为准,然后根据其中的时间,进行推算。假如第一
个包是10点整来的,然后ptime又是20ms,那么下一个包的时间就是10点又20毫秒。
media session是一个RtpSession对象,包含多种属性和方法。RtpScheduler中包含一个
RtpSession的队列,用来支持多媒体流。
值得一提的是,rtp_scheduler_schedule中有一个独特的"sleep",该sleep可以停顿10ms。
并且这个时间是绝对的,如果中间因为处理或者其他原因延迟了2ms,那么这个sleep停顿的就是
8ms。具体函数可以看一下posixtimer.c中的posix_timer_do实现。精确的计时使用select,精确
第 7 页 2022-4-27
流媒体分析
时间的取得很多使用gettimeofday这个函数,该函数在精确计时的时候非常有用。
单线程支持多路媒体流
对外是有一个sessionset,完全模拟了select的做法,对外提供的接口,也和标准select几
乎一样。主要的处理实现,还是在rtp_scheduler里面完成。模拟select的唤醒,使用了
pthread_cond_wait。
自适应的缓冲区算法
主要的实现都在jitterctl.c里面。
RTCP的实现
rtcp是不算很复杂的东西。ortp中,在RtpSession里面,即包含了rtcp的一些相关属性。需
要的时候,直接取出,然后组包发送就可以了。不过还要涉及到SDES。
SRTP的实现
见SRTP的说明
2.4. 程序运行逻辑
2.4.1. MEDIASTREAMER2
在这里我们简要的分析下程序加载的逻辑,从前面的描述过程中我们可以很容易看出MS的程序运行
逻辑。
注册所有的FILTER
调用FILTER的一次
性的方法
连接FILTER
启动线程
上图简要的描述了MS的程序加载逻辑,当然在调用的过程中具体的细节实现根据具体应用有所区别。
注册很好理解,见二次扩展部分就很容易理解,下面先描述下如何定义FILTER的前后逻辑流程.我们
以一个语音通讯的具体例子来描述.
执行FILTER上的方法
第 8 页 2022-4-27
流媒体分析
初始化连接器
MSRtpRecv(OUT)
连接
MSSpeexEC(OUT)
连接
MSWinSndWrite(IN
)
WinSndRead(OUT)
连接
MSSpeexEC(IN)
MSG729Dec(IN)
MSG729Dec(OUT)
连接
ms_ticker_new
MSSpeexEC(OUT)
连接
MSG729Enc(IN)
MSDtmfGen(IN)
Ms_ticker_attach
(WinSndRead)
MSDtmfGen(OUT)
连接
MSG729Enc(OUT)
连接
MSRtpSend(IN)
MSEqualizer(INT)
Ms_ticker_attach
(MSRtpRecv)
MSEqualizer(OUT)
连接
初始化连接器MSSpeexEC(IN)
根据上面流程描述,定义整个流程非常简单,只是需要注意最后的二个ATTACH,它是为了找到二个
FILTER的入口,一个为从采集语音的数据,是发起的源头,另外一个为RTP接收的FILTER,为接收的源
头。
流程定义完成后,下面我们将细化一下并描述这些FILTER被调用的过程。
线程启动
循环遍历ms_ticker_attach关联的FILTER可执行节点
读媒体流
处理回声
接收RTP数据
对数据解码
数据编码处理回声
通过上图可以知道,在线程启动后,首先找到ATTACH上的二个FILTER的节点指针,然后通过一个
第 9 页 2022-4-27
RTP发送播放数据
流媒体分析
递归来执行到最后一个节点。执行完成后再重新开始。下面的二个分支是不确定的,根据不同的流程设
置,应该调用的FILTER也不同。
2.4.2. ORTP
ORTP的发送处理流程
1,初始化ortp_init();
2,初始化调度线程ortp_scheduler_init();
3,设置媒体传输过程中有DTMF数据rtp_profile_set_payload;
4,创建一个发送的SESSIONsession=rtp_session_new(RTP_SESSION_SENDONLY);
5,设置是否使用调度任务rtp_session_set_scheduling_mode(session,1);
6,设置阻塞模式rtp_session_set_blocking_mode(session,1);
7,设置对端的地址rtp_session_set_remote_addr();
7,设置默认的编码格式rtp_session_set_send_payload_type(session,0);
8,设置退出的信号
9,得到数据发送数据rtp_session_send_with_ts
10,发送DTMF信号
11,关闭SESSIONrtp_session_destroy(session);
12,退出ortp_exit();
其实以上处理流程根本不需要用调度任务,因为只有一个SESSION,个人感觉没有必要.在多个
SESSION的状态下用调度任务比较合适.,结合语音的框架建议用非任务调度的方式,该描述在语音模块中
具体再说.
ORTP的接收处理流程
1,初始化ortp_init();
2,初始化ortp_scheduler_init();
3, 设置媒体传输过程中有DTMF数据.
4,创建一个接收的session=rtp_session_new(RTP_SESSION_RECVONLY);
5,设置是否使用调度任务 rtp_session_set_scheduling_mode(session,1);
6,设置阻塞模式rtp_session_set_blocking_mode(session,1);
7,设置本地地址rtp_session_set_local_addr();
8,设置默认的编码格式rtp_session_set_payload_type(session,0); pcm
9,设置回调rtp_session_signal_connect();
10,接收数据rtp_session_recv_with_ts(session,buffer,160,ts,&have_more);
11,关闭rtp_session_destroy(session);
12,ortp_exit();
第 10 页 2022-4-27
流媒体分析
3. 编译流程
3.1. 平台描述
MS的代码由于是纯粹的C编写,很容易支持各种平台,目前我在WINXP上编译。而且目前的应用估
计90%都会用到WINDOWS系统。所以下面的描述都是基于这个平台。
3.2. 依赖环境
这里的依赖环境是说要编译MS和ORTP库还需要那些库文件的支持。如果不考虑各种编码,其依赖
的库也不太多。
ORTP依赖的库主要是SRTP和OPENSSL的库。
SRTP:
简单介绍:安全的适时传输协议,一个Cisco公司人写的
下载地址:/
注意事项:由于ORTP中要集成了SRTP库,所以在编译ORTP的时候要找SRTP的头文件。
OPENSSL:到处都有,在这里最简单的办法是引用OPENSSL的头文件和加载二进制的代码。
RTP: 见RTP协议简单描述。
MS库主要依赖的库主要有:swscale quartz dmoguids strmiids strmbasd libtheora
libavcodec libgsmcodec ortp speex speexdsp
quartz dmoguids strmiids strmbasd :这四个库主要是DirectShow中产生的。主要用来处理
一些与音视频有关的多媒体任务,比如音视频采集、回放等。
具体要安装DirectShow,我下载的是,安装后编译DX9
SDKSamplesC++DirectShowBaseClasses这个目录下的文件,产生strmbasd这个库,别的库文件
安装之后就存在了。
Swscale,libavcodec:从FFMPEG中提取,我们可以直接用这个库的二进制文件和头文件。FFmpeg
是一套可以用来记录、转换数字音频、视频,并能将其转化为流。
下载地址: svn checkout svn:///ffmpeg/trunk ffmpeg
或者git clone git:///ffmpeg/
cd ffmpeg
git clone git:///libswscale/
libtheora:Theora 是一个开源的视频编解码器,属于Ogg项目的一部分。
下载地址:/releases/theora/
Speex:是一套专门用于压缩声音的库,由于其专门针对声音,所以压缩声音的性能非常高.同时
也可以用于回音处理,关于回声处理,我以前以为在MS中是通过微软的API处理的,经过研究发现还
是通过SPEEX来实现,只不过版本不同而已.
下载地址:/downloads/
第 11 页 2022-4-27
流媒体分析
3.3. 编译设置
将上面的依赖库文件编译出来后,编译MS库和ORTP库就非常简单了,将头文件的路径指向这些头
文件目录,就可以了。
Ortp:
头文件目录:......win32-bininclude" /I "....include" /I "....includeortp" /I
"....src" /I "....buildwin32nativeinclude"
库文件目录:......win32-binlib
库文件:
Ms库:
头文件目录::......win32-bininclude" /I "....include" /I "....includeortp"
/I "....src" /I "....buildwin32nativeinclude"
库文件目录:......win32-binlib
库文件:libswscale.a
.a
4. 二次扩展
4.1. 功能修改
在输出部分的修改:
目前为调试方便将所有的信息输出,采用DEBUGVIEW查看的方式,而且对每条信息标志出了线程号,时
间,错误级别等。
设备检测的修改:
去掉动态检测声卡设备的线程,该线程每5秒检测一次声卡设备,感觉这种动态的应用非常少,而
且占用大量的CPU,因此屏蔽了该功能。
4.2. 编/解码的扩展
在MS库中做编码的添加修改,非常方便,但是个人感觉还是不太简单,因为很多时候对编码的修改
不是一个流媒体输入和流媒体的输出那样简单。必须对编码应该有所了解。
目前我只对音频部分做了G729的添加,在视频部分后续将继续介绍。
4.2.1. ORTP扩展
个
人认为一个好的RTP协议应该不象ORTP协议配置流媒体类型这样复杂,仅仅因为要支持一种新的
媒体编码就需要将程序编译一遍,感觉还是不太容易接受。
以下以G729A为例:添加G729编码.,G729在这个库中已经定义好了。以下的说明是为描述如何让
ORTP支持一个新的编码.
第 12 页 2022-4-27
流媒体分析
ORTP部分具体过程如下:
1,在AVPROFILE.C中添加G729的定义.描述:
PayloadType payload_type_g729={
TYPE( PAYLOAD_AUDIO_PACKETIZED),
CLOCK_RATE(8000),
BITS_PER_SAMPLE( 0),
ZERO_PATTERN(NULL),
PATTERN_LENGTH( 0),
NORMAL_BITRATE( 8000),
MIME_TYPE ("G729"),
CHANNELS(1)
};
简单描述: 类型为一个音频的数据包,时钟频率为8000,类型为729,占用一个通道.表示RTP分
组第一个字节的取样时刻。其初值为随机数,每个采用周期加1。如果每次传送20ms的数据,由于
音频的采样频率为8000Hz,即每20ms有160次采样,则每传送20ms的数据,时戳增加160.
2,同时在这个文件中的av_profile_init函数中加入
rtp_profile_set_payload(profile,18,&payload_type_g729);
3,定义好后我们必须把其导出供其它应用来使用.在PAYLOADTYPE.H中加入
VAR_DECLSPEC PayloadType payload_type_g729
;
4.2.2. MEDIASTREAMER2扩展
在ORTP中加入完成后,下面将要扩展MS2的库,这个过程其实也可以简单的这样理解,函数提供一
个媒体流的输入接口和一个媒体流的输出接口,来处理媒体信息。在处理前和处理后可能有一系列的处
理,如在处理过程中需要共享部分信息。
1, 首先定义一个结构体
typedef struct G729State
在上面这个结构体中我们主要关注这个BUF,用于来存储数据。
2, 初始化编码的函数和函数指针
MSFilterDesc ms_g729_enc_desc={
MS_G729_ENC_ID,
"MSG729Enc",
N_("The G729 full-rate codec"),
MS_FILTER_ENCODER,
"g729",
1,
1,
enc_init,
NULL,
enc_process,
NULL,
enc_uninit,
NULL
第 13 页 2022-4-27
流媒体分析
};
这里至少要定义三个函数,初始化,处理,注销。这几个函数处理函数必须不为空,除此之外我们
还可以在处理前和处理后添加一些处理。其它描述见数据结构说明。
3, 初始化(enc_init)
首先我们需要初始化一个BUF,用于处理中来存放数据,由于这个地方是用动态分配内存的方式,
所以对应的注销中有释放处理,同时要初始化G729库的一些处理。
4, 处理enc_process
具体的处理方式和编码算法有很大的关系,该函数并非每次都要有输出流和输入流的处理,如果
输入的数据和编码算法要输入的数据包大小不一致的时候,可以不处理,当数据包的大小满足条件
的时候则处理。
1, 首先从输入数据的指针中取数据放到我们在初始化BUF中。
2, 判断目前的BUF是否能满足算法所要求的数据。
3, 如果不满足则等下次来处理。
4, 如果满足则每次取等量的输入包,开始编码,处理后的包放到输出队列中。
5, 如果发现还有大小相同的包,则循环处理,直到输入的包小于要处理的包为止。
6, 退出过程。
7, 在这个函数成功的执行后该编码过程就完成了,后面的发送FILTER则可以判断函数的输出
是否为空,如果不为空则从输出队列上取数据,发送出去。
5, 注销(enc_uninit)
当FILTER被UNLINK的时候会释放掉,先前初始化的操作。
6, 导出函数指针
MS_FILTER_DESC_EXPORT(ms_gsm_enc_desc)
7, 上面2-6只定义了G729的编码函数,下面需要定义接收部分收到数据包后如何处理(解包处理)。
8, 初始化解码的函数和函数指针
MSFilterDesc ms_g729_dec_desc={
MS_G729_DEC_ID,
"MSG729Dec",
N_("The G729 codec"),
MS_FILTER_DECODER,
"g729",
1,
1,
dec_init,
NULL,
dec_process,
NULL,
dec_uninit,
NULL
};
9, 解包初始化(dec_init)
10, 解包处理(dec_process)
第 14 页 2022-4-27
流媒体分析
简单的说就是得到输入包上的数据,解包后放到输出上就可以,输出的数据可以后续处理。
11, 在ALLFILTERS。H定义函数类型的声明
MS_G729_ENC_ID,MS_G729_DEC_ID
12, 在ALLCODESCS。H中声明函数
extern MSFilterDesc ms_g729_dec_desc;
extern MSFilterDesc ms_g729_enc_desc;(编码,上面没有说)
13, 初始化结构体ms_filter_descs[],在末尾加上
&ms_g729_dec_desc,
&ms_g729_enc_desc,
以上为MS中添加G729的过程完成。
4.2.3. 调用
在ORTP和MS中这些部分完成后,我们所要做的就是开始调用和调试了。这个过程很简单。
stream->encoder=ms_filter_create_encoder(18);
//18为ORTP中关于G729的定义
stream->decoder=ms_filter_create_decoder(18);
这样G729的编码就加上去了,并可以使用了。
4.3. 插件的扩展
4.3.1. ORTP中的配置
4.3.2. MS中的配置
4.3.3. 遵循的函数接口标准
4.3.4. 调用
第 15 页 2022-4-27
流媒体分析
5. 数据结构
5.1. 框架数据结构
首先需要定义一些函数指针来连接和外部的函数接口,在这里通过几个简单函数指针来实现的。以
下是关于所有FILTER的管理的数据结构,通过这些数据结构和控制的API来管理FILTERS。
5.1.1. 函数指针定义:
typedef void (*MSFilterFunc)(struct _MSFilter *f);
作用: 定义FILTER初始化(INIT),处理前(PREPROCESS),处理(PROCESS),处理后(POSTPROCESS)
和注销(UNINIT)的函数指针。
typedef int (*MSFilterMethodFunc)(struct _MSFilter *f, void *arg);
作用:定义FILTER和设置FILTER选项
typedef void (*MSFilterNotifyFunc)(void *userdata , unsigned int id, void *arg);
作用:定义FILTER中回掉函数的入口
定义FILTER的类别
MS_FILTER_OTHER, 其它类型
MS_FILTER_ENCODER 编码
MS_FILTER_DECODER 解码
5.1.2. MSFilterMethod
定义FILTER的函数列表,为一次性调用,如果FILTER上的5个主要函数指针不能满足需求的时候
使用。
字段名
id
method
类型
Int
MSFilterMethodFunc
描述
函数ID
函数方法
5.1.3. MBLK_T
MBLK_T的主要作用是将一系列的数据流组装在一起,形成一个大的数据流,每个节点中的BUF,又有指
向BUF头和尾的指针
字段名
b_prev
类型
struct msgb *
长度
Sizeof(msgb)
第 16 页
描述
前一个数据包
2022-4-27
流媒体分析
b_next
b_cont
b_datap
b_rptr
b_wptr
struct msgb *
struct msgb *
struct datab *
unsigned char *
unsigned char *
Sizeof(msgb)
Sizeof(msgb)
Sizeof(datab)
后一个数据包
数据
首指针
尾指针
5.1.4. MSFilterDesc
FILTER的函数指针定义,下面这个结构为FILTER的核心描述,所有的FILTER的方法和属性都在这里
定义。
字段名
id
name
text
category
enc_fmt
ninputs
noutputs
init
preprocess
process
postprocess
uninit
methods
类型
MSFilterId
const char *
const char *
MSFilterCategory
const char *
int
int
MSFilterFunc
MSFilterFunc
MSFilterFunc
MSFilterFunc
MSFilterFunc
MSFilterMethod *
描述
filter的ID号,为唯一的ID,
filter 的名称
描述,这个FILTER是实现什么功能
类别,定义了编码,解码或者是其它
必须被设置,在编解码的FILTER中
定义输入的数字,如果是是播放的FILTER
则为0,如果是录音则为1
同上面的输入描述
每个FILTER初始化的函数指针
在被调用前的函数指针
过程的函数处理
处理完成后的指针
结束,释放资源
一些可选的函数指针,当上述函数指针不能
处理的时候,可以通过该指针来实现
5.1.5. MSFilter
FILTER的完整定义
字段名
desc
inputs
outputs
notify
ticker
上面二个数据结构完整的定义了一个FILTER,但是我们在执行过程中则需要通过数据结构来将这些
FILTER串连起来。该结构体通过create/link/unlink/destroy方法来管理和维护。
第 17 页 2022-4-27
类型
MSFilterDesc *
MSQueue **
MSQueue **
描述
函数指针
输入的队列
输出的队列
MSFilterNotifyFunc 注册回调函数
struct _MSTicker * 调度,执行列表上的FILTER,为一个线程
流媒体分析
5.1.6. MSConnectionPoint
本来上面的定义就可以完全的描述和管理好所有的FILTER了,但是在最新的版本中又提供了一种数
据结构来管理FILTER的流程图。
字段名
filter
pin
类型
MSFilter *
int
描述
Filter对象
FILTER的输出,可以有多个
5.2. 传输数据结构
字段名
type
clock_rate
mime_type
channels
recv_fmtp
send_fmtp
类型
int
int
char *
int
char *
char *
描述
包类型 ,语音或者是视频
RTP的时钟频率 如8000,4400等
连续音频数据
actually the submime, ex: pcm, pcma, gsm
通道数
用于DTMF数字信号、电话音和电话信号的
RTP负载格式
见注释
bits_per_sample char
如果在SDP消息中包含有 a=fmtp 字段,则表示发送方有能力接受DTMF(events 0 through 15),
拨号和回铃音。
例如:若payload-type为100, 则 a=fmtp:100 0-15,66,70
当接受方在invite请求中收到a=fmtp信息,
如果接受方不接受其中的任何一种信息,则在响应消息中不包含a=fmtp信息;
如果接受方不支持a=fmtp中的其中一种(如不支持66,70),则在响应的消息中只包含有1-15
字段;
6. API描述
6.1. 传输API
ortp_init(); 主要初始化SOCKET库文件,加载一个配置信息.
ortp_set_log_level_mask:设置LOG输出方式.
rtp_profile_set_payload:设置传输编码
rtp_profile_clone_full:拷贝一个配置环境
ortp_ev_queue_new:创建一个事件队列
rtp_session_register_event_queue:注册事件队列,.
rtp_session_compute_recv_bandwidth:显示接收的带宽,在不同的编码下可以比较性能.
第 18 页 2022-4-27
流媒体分析
rtp_session_compute_send_bandwidth :发送时的带宽.
rtp_profile_destroy() 释放环境变量.
6.2. 语音控制API
audio_stream_start_with_files;播放文件
audio_stream_play; 播放流文件
audio_stream_record录音;
audio_stream_play_received_dtmfs播放DTMF的声音
audio_stream_enable_echo_limiter 激活回声限制
audio_stream_set_mic_gain设置MIC的阀值
audio_stream_enable_noise_gate激活噪音处理
audio_stream_enable_equalizer 平衡处理,没有研究过?
audio_stream_stop 停止处理
ring_start 响铃
ring_stop 停止震铃
audio_stream_send_dtmf 发送DTMF
audio_stream_set_default_card设置默认的声卡
audio_stream_start_full 开始一个音频通道
6.3. 视频控制API
6.4. 编/解码API
6.5. FILTER管理API
注册插件.具体见插件的扩展流程
void ms_filter_register(MSFilterDesc *desc);
根据一个名称得到FILTER的编码函数指针,如果失败则返回空指针.如PCMU,PCMA,SPEEX,GXM
MSFilterDesc * ms_filter_get_encoder(const char *mime);
根据一个函数名得到FILTER编码的函数指针,如果失败则返回空
MSFilterDesc * ms_filter_get_decoder(const char *mime);
第 19 页 2022-4-27
流媒体分析
根据一个名称创建一个FILTER,空则表示失败
MSFilter * ms_filter_create_encoder(const char *mime);
根据一个名称创建一个解码的FILTER
MSFilter * ms_filter_create_decoder(const char *mime);
检查是否支持该名称的编解码
bool_t ms_filter_codec_supported(const char *mime);
根据ID来创建一个FILTER
MSFilter *ms_filter_new(MSFilterId id);
创建一个编码根据FILTER名称
MSFilter *ms_filter_new_from_name(const char *name);
创建一个FILTER根据FILTER函数,一般用于内部描述.
MSFilter *ms_filter_new_from_desc(MSFilterDesc *desc);
将FILTER之间关联起来,连接一个输出的插脚到另外一个FILTER输入的插脚,将一个FILTER的数据输出
流转移到数据的输入流中.
输出数据流的FILTER,输出的索引,输入流的FILTER对象,输出的索引,0成功,-1表示失败
int ms_filter_link(MSFilter *f1, int pin1, MSFilter *f2, int pin2);
解除FILTER之间的流程关系,并停止FILTER的工作
int ms_filter_unlink(MSFilter *f1, int pin1, MSFilter *f2, int pin2);
调用FILTER上的设置或者得到设置的方法.F表示该FILTER,ID表示该FILTER的ID,ARG则表示该FILTER
该方法所需要带的参数.
int ms_filter_call_method(MSFilter *f, unsigned int id, void *arg);
调用FILTER的设置方法,该函数常用于无数据传入出的FILTER方法.
int ms_filter_call_method_noarg(MSFilter *f, unsigned int id);
在FILTER上设置一个CALLBACK函数.
void ms_filter_set_notify_callback(MSFilter *f, MSFilterNotifyFunc fn, void *userdata);
得到FILTER的ID号
MSFilterId ms_filter_get_id(MSFilter *f);
通过一个FILTER得到该FILTER图上邻近的FILTER,当调用者不需要的时候由其释放.
MSList * ms_filter_find_neighbours(MSFilter *me);
释放FILTER对象
第 20 页 2022-4-27
流媒体分析
void ms_filter_destroy(MSFilter *f);
初始化一个连接器,该方法为后期提供.
void ms_connection_helper_start(MSConnectionHelper *h);
7. MS与SIP集成
1, 注册
目的:通过SIP协议注册到,服务器上.(这个应该和语音模块关系不大)
个人理解:由于我们的服务器可能采用第三方的商业IPPBX,而我们的软终端肯定要注册到自己的域服
务器,需不需要到IPPBX上再注册,这可能和对方的实现有关.
2, 发起呼叫
目的:通过在线列表呼叫一个软终端或者桌面电话或者移动电话.
个人理解:在这里SIP协议应该提供一个简单的API来让MS部分来生成SDP包,同时提供从SDP取编
码方案的API.也提供协商成功或者失败的控制.在这里应该不关注是INVITE还是ACK包的处理.
1,发送呼叫请求.生成SDP包
2,返回成功或者失败
3,如果成功则取SDP包,判断
4,开始连接媒体流
3, 取SIP协议中SDP包的信息
目的:取SDP包中的编码个数,和编码的具体描述等.
个人理解:能提供一个API
4, 组装SDP包
目的:让对端知道本端具有什么样的编码格式.
个人理解:也需要一个封装好的API
8. MS提供给界面控制的函数
1, 编码设置
编码设置: 名称,采样频率(HZ),状态,最小速率,参数设置
2, 声音控制
播放设备,捕获,铃声
3, 视频控制
输入设备,视频大小
4, 声卡的检测
5, 摄像头的检测
6, 噪音控制
7, 回音控制
第 21 页 2022-4-27
流媒体分析
第 22 页 2022-4-27
8, 语音通道的控制
9, 暂停通话
10, 停止通话
11, 注销
9. MS中其它描述


发布评论