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中其它描述