怎么在mediastreamer2库进行二次开发及添加自定义filter?

mediastreamer2提供的Filter链接为Graph的方式,通过代码让使用者将各种自带的msfilter结构链接起来,使之可以灵活的定义多媒体流。通过自定义插件,可以给mediastreamer2框架加入新功能。要自定义一个模块,需要按照规范定义一系列数据结构,其中最关键的是描述插件功能的结构体MSFilterDesc,该结构体包含了插件名字、类型、输入输出端个数和处理函数。定义了结构体后实现有关函数,在mediastreamer2中,数据流通过mblk_t结构体来承载,mblk_t中有两个指针b_wptr和b_rptr,分别对应于分配给的一块内存中,开始和结束地址。当通过函数ms_queue_get从输入端数据队列获取mblk_t后,从b_rptr读取数据,处理后的数据拷贝入新建的mblk_t中,边写入边递增指针b_wptr,标记新的结束地址,直到输入端的数据包中数据处理完毕并填入到下一输出包,通过ms_queue_put将包发给下一滤镜(filter)队列,并通过freemsg将输入的mblk_t释放!

mediastreamer2是由开源VoIP客户端项目Linphone设计并使用的一个多媒体框架,mediastreamer2通过oRTP库实现了音视频的RTP、SRTP和ZRTP传输。该框架通过类似于DirectShow所提供的Filter链接为Graph的方式,通过代码让使用者将各种自带的msfilter结构链接起来,使之可以灵活的定义多媒体流。

mediastreamer2源码分析及自定义filter共包含3篇博客,分别是:怎么在mediastreamer2库进行二次开发及添加自定义filter 怎么在mediastreamer2库进行二次开发及添加自定义filter?以及mediastreamer2添加自定义filter实现linphone加密语音通信

Mediastreamer2中的两个重要概念:filter、graph

  • filter:Mediastreamer2中处理媒体数据的组件,1个filter可以有多个input、output,这些inputs、outputs其实就是缓冲区队列。

  • graph: 多个连在一起的filter管理器,通过系统管理和调度,它把媒体流从1个fiilter的output传输到下一个filter的input。

graph和filter的关系如图所示:

mediastreamer filter

本文来自秒拍视频下载工具

除了自带的Filter,还可以通过编写插件的方式,加入自己的编码器、插件等新功能。在该博客中,采用mediastreamer2传输音频流,通过自定义的HC-256’加密插件,原始音频流将在编码后和解码前分别加解密,以实现加密语音传输。

mediastreamer2框架主要用于VoIP中,声卡通过话筒采集到声音,输出原始Wave音频到编码器压缩后,再通过RTP协议发送到接收端;接收端得到数据,解压为Wave音频,写入到声卡以输出至耳机。mediastreamer2很简单的将这一过程模块化,以方便开发人员使用,如代码片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
MSSndCard *sndcard=ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());

MSFilter *soundread=ms_snd_card_create_reader(captcard);
MSFilter *encoder=ms_filter_create_encoder("PCMU");
MSFilter *rtpsend=ms_filter_new(MS_RTP_SEND_ID);

MSFilter *soundwrite=ms_snd_card_create_writer(playcard);
MSFilter *decoder=ms_filter_create_decoder("PCMU");
MSFilter *rtprecv=ms_filter_new(MS_RTP_RECV_ID);

RtpSession *rtp_session = *** your_ortp_session *** ;
ms_filter_call_method(rtpsend,MS_RTP_SEND_SET_SESSION,rtp_session);
ms_filter_call_method(rtprecv,MS_RTP_RECV_SET_SESSION,rtp_session);

通过一系列API函数创建了声卡采集和输出、编码解码、RTP发送接收等滤镜,而将Filter连接,则通过以下代码片段:

1
2
3
4
5
ms_filter_link(stream->soundread,0,stream->encoder,0);
ms_filter_link(stream->encoder,0,stream->rtpsend,0);

ms_filter_link(stream->rtprecv,0,stream->decoder,0);
ms_filter_link(stream->decoder,0,stream->soundwrite,0);

即通过ms_filter_link便可以将这些Filter按照顺序链接起来,形成可用的Graph。然后还需要使用函数void ms_ticker_attach(MSTicker , MSFilter ),将Graph加入到Ticker中,让Ticker新建线程,按照顺序轮流调用每一个Filter中定义的处理函数,将上一个管道的数据处理后传入下一个管道,以实现多媒体数据在Filter中的实时处理。

更多关于mediastreamer2的开发和自定义filter,请参考下一篇博文:怎么在mediastreamer2进行二次开发和自定义filter