linphone mediastream2 分析-双向录音机

来源:互联网 发布:网络解锁 编辑:程序博客网 时间:2024/06/06 00:24

(转载请标明出处,请勿用于商业用途)

http://blog.csdn.net/linux_embedded/article/details/8957482

 

linphone是一个轻量级voip客户端,linphone的架构设计十分的清晰,其底层音视频引擎mediastream2是一个独立的模块,基于它可以很容易的实现各种音视频的应用没。本文中所说的linphone 双向录音功能就是基于mediastream2架构的。

linphone 整体架构

linphone拥有自己的用户接口和核心引擎(音频/视频引擎),允许在相同的函数基础上建立不同的用户接口。

  • 用户接口

GTK+用户接口

命令行接口(linphonec, linphonecsh)

iPhone用户接口(基于objective C)

基于Java实现的Andorid应用

  • liblinphone,核心引擎。提供了高度容易扩展的函数接口,它是一个功能强大的SIP VOIP SDK,我们可以基于该框架实现任意的语音/视频应用。liblinphone基于下列组件实现:

mediastream2,功能强大的音/视多媒体SDK,用于创建和处理音/视流

oRTP,简单的RTP处理库

eXosip,SIP UA 库,其基于libosip2实现

 

linphone和liblinphone都是使用C语言实现的,下面为linphone的整体结构。

 

 

mediastream2实现机制

mediastream2功能强大,体积小,特别适合嵌入式设备的音视频流的处理。mediastream2为一个独立的处理音视频流的库,它能够完成关于音视频流的捕获、接收、发送、编码、解码、翻译等功能,基于它可以实现各种音视频的应用。下面为mediastream2具体

特性:

  1. 可以捕获、重放多种基于各种音频架构(ALSA, AudioUnits, AudioQueue, WaveApi)的音频流。
  2. 接收、发送RTP数据包。
  3. 支持多种音视频编码方式:audio:speex, G711, GSM, iLBC, AMR, AMR-WB, G722, SILK, G729; video: H263, theora, MPEG4, H264 and VP8.
  4. 支持音频的wav格式文件的读取和保存。
  5. 捕获摄像头的YUV图片格式,并对其以优化。
  6. 立体声输出。
  7. 回声消除,基于speex回声消除机制(webrtc AEC机制)。
  8. 支持音频会议,支持音频参数均衡。
  9. 音量控制。
  10. 具有IEC NAT穿越动能。
  11. 自动比特率控制算法:基于RTCP反馈信息。

H264, ILBC, SILK, AMR, AMR-WB and G729是以插件的形式整合到mediastream2架构中去的。

 

设计:

mediastream2中每一个处理过程实体都被定义为一个MSFilter结构,每一个MSFiter有一个(若干个)输入和一个(若干个)输出,通过输入、输出将各个实体连接起来。下面为一个简单的例子:

[cpp] view plaincopy
  1. MSRtpRecv --> MSSpeexDec --> MSFileRec  
  1. MSRtpRecv:接收网络上的数据包、解包,并将它们输出到下一个Filter。
  2. MSSpeexDec:假设音频解码器为speex,它会decode音频数据包,并作为声卡播放filter或wav文件保存filter的输入。
  3. MSFileRec:将语音数据保存为wav格式的文件(输入确保为:Linear 16 pcm格式)

负责调度的对象为MSTicker,它一个独立的线程,其每10ms被唤醒一次,然后它会处理他所管理的媒体链的数据。可以有多个MSTicker同时运行吗,例如,处理音频的Ticker和处理视频的Ticker

,或者不同的处理器中会运行不同的Ticker。

利用mediastream2的Filter机制,我们可以很容易的实现我们需要的功能,我们也可以很容易的基于Filter机制扩展自己需要的功能。双向录音功能就是基于Tee和MSFileRec两个Filter实现的。

linphone双向录音功能实现方案

基于mediastream2的音频处理架构,利用Tee和MSFileRec嵌入到的音频处理流程中,实现linphone的双向录音功能。录音分为发送和接收两个处理流程。下面分别为两个处理流程:

  1. 发送过程录音:
     

   2. 接收过程录音:

代码实现

mediastream2录音功能处理流程如下:

按照上面的流程图,主要分为音频处理初始化、开始录音、结束录音几部分介绍一下具体的实现。

音频流初始化

mediasream2中音频流处理初始化都是在函数audio_stream_start_full完成的,我们需要把Tee、FileRec两个Filter加入到音频处理过程中,并对他们做一些必要的初始化工作,例如,设置wav保存时的sample rate等。下面是我们需要添加的处理:

修改数据结构struct _AudioStream,添加Recv_Tee、Snd_Tee、Recv_FileRec、Snd_FileRec

[cpp] view plaincopy
  1. struct _AudioStream{  
[cpp] view plaincopy
  1. MSFilter *Recv_Tee;  
[cpp] view plaincopy
  1. MSFilter *Snd_Tee;  
[cpp] view plaincopy
  1. MSFilter *Recv_FileRec;  
[cpp] view plaincopy
  1. MSFilter *Snd_FileRec;  
[cpp] view plaincopy
  1. };  

创建、初始化Recv_Tee、Snd_Tee、Recv_FileRec、Snd_FileRec

[cpp] view plaincopy
  1. //创建Filters  
[cpp] view plaincopy
  1. stream->Recv_Tee = ms_filter_new(MS_TEE_ID);  
  2. stream-Snd_Tee  = ms_fiter_new(MS_TEE_ID);  
  3. stream->Recv_FileRec = ms_filter_new(MS_FIlE_REC_ID);  
  4. stream->Snd_FileRec = ms_filter_new(MS_FILE_REC_ID);  
[cpp] view plaincopy
  1. //Set Filters   
[cpp] view plaincopy
  1. ms_filter_call_method(stream->Recv_FileRec, MS_FILTER_SAMPLE_RATE, &sample_rate);//设置wav文件采样率  
[cpp] view plaincopy
  1. ms_filter_call_method(stream->Snd_FileRec, MS_FILETER_SAMPLE_RATE, &sample_rate);  
[cpp] view plaincopy
  1.    
[cpp] view plaincopy
  1. //add Revc_Tee、FileRec to receive graph  
[cpp] view plaincopy
  1. ms_connection_help_link(&h, encoder , 0 ,0);  
[cpp] view plaincopy
  1. ms_connection_help_link(&h , stream->Recv_Tee , 0 , 1);  
[cpp] view plaincopy
  1. ms_filter_link(stream->Recv_Tee , 0 , stream->Rec_FileRec , 0);  
[cpp] view plaincopy
  1.    
[cpp] view plaincopy
  1. //add Snd_Tee、FileRec to send graph  
[cpp] view plaincopy
  1. ms_connection_help_link(&h , decoder , 0 , 0);  
[cpp] view plaincopy
  1. ms_connection_help_link(&h, stream->Snd_Tee , 0 , 1);  
[cpp] view plaincopy
  1. ms_filter_link(stream->Snd_Tee , 0 , stream->FileRec , 0);  
[cpp] view plaincopy
  1. ms_conncetion)_help_link(&h , stream->sound_write ,0 ,-1);  


 启动录音

一般在 linphone中,当一个会话建立成功,就会创建处理音频流Filter链,这时就会调用形如audio_stream_record()的函数录音,此函数有一个参数为wav文件的保存路径和文件名。

 

[cpp] view plaincopy
  1. ms_filter_call_method_noarg(st->soundwrite,MS_FILE_REC_CLOSE);   
  2. ms_filter_call_method(st->soundwrite,MS_FILE_REC_OPEN,(void*)filename);  
  3. ms_filter_call_method_noarg(st->soundwrite,MS_FILE_REC_START);   


本文创建了两个函数:audio_stream_recv_rcord()、audio_stream_snd_record()分别用来处理两个方向的录音。

结束录音

当通话结束时,linphone会自动结束录音,并释放Filters占用的资源。此项工作在audio_stream_stop中完成。

[cpp] view plaincopy
  1. ms_filter_call_method_noarg(stream->Recv_FileRec , MS_FILE_REC_SOTP);  
  2. ms_filter_call_method_noarg(stream->Snd_FileRec , MS_FILE_REC_STOP);  
[cpp] view plaincopy
  1. ms_connection_help_unlink(&h , stream->Recv_Tee , 0 , 1);  
[cpp] view plaincopy
  1. ms_conncetion_help_unlink(&h , stream->Recv_FileRec , 0 ,0);  
[cpp] view plaincopy
  1. ms_connection_help_unlink(&h , stream->Snd_Tee , 0 ,1);  
[cpp] view plaincopy
  1. ms_filter_unlink(stream->Snd_Tee , 0 , stream_FileRec , 0);  

 

如上就是linphone的双向录音功能实现的整个过程,该方法具有一定的通用性,在其他的一些VoIP或音频处理应用中我们同样可以利用该方案实现录音功能。
0 0
原创粉丝点击