Asterisk媒体处理分析_第1页
Asterisk媒体处理分析_第2页
Asterisk媒体处理分析_第3页
Asterisk媒体处理分析_第4页
Asterisk媒体处理分析_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Asterisk媒体处理分析1 媒体转换过程 以下讲媒体转换有两种方式除外: n 两端编码方式一致如两端语音编码都是g729; n 一端是g711a,另一端是g711u时 Asterisk媒体处理过程与业务无关,是一个统一的过程,处理对象有RTP和File,不管外界RTP或File输入格式如何,进入Asterisk后默认转换为signed linear格式,从Asterisk输出(发送或写文件)时再从slinear格式转换为外界RTP或File格式(细节参见RTP Translate): 上图分为四个方向 1. RTP to RTP(正常通话流程) 2. RTP to File(录音流程) 3

2、. File to RTP(放音流程) 4. File to File(文件格式转换流程) 复杂业务的媒体处理可以分解为以上四个方向处理流程,复杂业务可能包含其中几种流程,每个业务的媒体处理可以用下图表示:1设置channel媒体转换路径(如g723=gsm)2 源媒体转换为slinear格式(如g723=slinear)4 Slinear转换为目的格式(如slinear=gsm)3 媒体处理(如混音)5 发送/写文件1. 设置转换路径,即设置源媒体格式与目的媒体格式; 2. 把输入媒体格式进行转换为slinear,如果输入媒体为slinear可省略本步骤; 3. 媒体处理,如混音等,一般可以

3、省略; 4. 把slinear格式媒体转换为目的媒体格式,如果目的媒体格式为slinear可省略本步骤; 5. 把转换后的媒体打包发送或写到本地文件。 1.1 RTP to RTP RTP to RTP适用于正常通话流程。 Channel收到RTP包时经过分析可以得到媒体格式,每个channel保存读和写的媒体格式信息,读RTP时使用步骤1和2,发送RTP时使用步骤4和5,channel的结构参见媒体转换相关结构,channel里保存媒体转换信息结构ast_trans_pvt和文件流描述结构ast_filestream(见文件流)。 下图为一个正常通话的编码转换过程,通话一端适用ilbc编码另

4、一端使用gsm编码:从上图看出,通话两端的语音编码进入asterisk后都转换为asterisk内部编码slinear后,发送时再被转换为目的语音编码。 下图说明一端使用g711a,另一端使用g711u时不需要转换为asterisk内部编码slinear,而是alaw和ulaw两种编码直接进行转换:1.2 RTP to File RTP to File适用录音流程,包含步骤1、2、4、5。 例:g729.cap语音还原为gsm格式文件过程:1.3 File to RTP File to RTP适用于放音流程,与RTP to File流程一样也包含步骤1、2、4、5。 1.4 File to F

5、ile File to File适用于文件格式转换,与RTP to File/File to RTP一样也包含步骤1、2、4、5。具体实例可参见附录。 1.5 混合流程 混合流程用到以上四个流程中的某几个复杂的业务有可能是混合流程,如Voicemail包含File to RTP和RTP to File流程,具体参见voicemail函数调用过程。 2 RTP处理 2.1 RTP init 在创建 sip_channel时,rtp fd同时被创建并加进channel的fds,通过poll进行监控。 sip_new - tmp-fds0 = ast_rtp_fd(i-rtp); 2.2 RTP R

6、ead Poll监控到rtp fd有读事件时进行read; ast_rtp_read中进行RTP解包; 读RTP过程中会调用ast_translate函数进行媒体转换,一般转换为slinear格式。 具体函数调用过程如下: wait_for_answer - ast_waitfor_n(watchers, pos, to); - ast_waitfor_nandfds - poll - f = ast_read(winner) - struct ast_frame *ast_read(struct ast_channel *chan) - static struct ast_frame *_a

7、st_read(struct ast_channel *chan, int dropaudio) - f = chan-tech-read(chan)即static struct ast_frame *sip_read(struct ast_channel*ast) / ast_translate - static struct ast_frame *sip_rtp_read(struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) - ast_set_read_format/ast_set_write_format/f = ast

8、_rtp_read(p-rtp) RTP解包 - recvfrom 2.3 RTP Send 发送RTP时会调用ast_translate函数进行媒体转换,从slinear格式转换为目的媒体格式,ast_rtp_raw_write函数中对RTP进行组包。具体函数调用流程如下:wait_for_answer - f = ast_read(winner) - int ast_write(struct ast_channel *chan, struct ast_frame *fr) - ast_set_write_format/ast_translate/res = chan-tech-write(

9、chan, f) 即static int sip_write(struct ast_channel *ast, struct ast_frame *frame) - int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f) - ast_rtp_raw_write(rtp, f, codec) RTP组包- sendto2.4 RTP translate 2.4.1 媒体转换相关结构ast_channel结构中writetrans和readtrans指向ast_trans_pvt结构,writetrans和readtrans通过as

10、t_translator_build_path创建; ast_translator 结构中保存媒体转换源编码格式(srcfmt),目的编码格式(dstfmt),转换回调(frameinframeout): 以g729编码为例初时化ast_translator结构:2.4.2 媒体转换流程 2.4.2.1 注册编码 把某种编码ast_translator注册到tr_matrix全局变量: ast_register_translator(t) (如res = ast_register_translator(&g729tolin) - int _ast_register_translator(str

11、uct ast_translator *t, struct ast_module *module) - static void rebuild_matrix(int samples)2.4.2.2 设置编码转换路径 static struct ast_frame *sip_rtp_read(struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) - int ast_set_read_format(struct ast_channel *chan, int fmt) / int ast_set_write_format(struct

12、 ast_channel *chan, int fmt) - static int set_format(struct ast_channel *chan, int fmt, int *rawformat, int *format,struct ast_trans_pvt *trans, const int direction) - struct ast_trans_pvt *ast_translator_build_path(int dest, int source) 调用ast_translator_build_path函数,在全局变量tr_matrix中查找对应的ast_translat

13、or创建ast_trans_pvt并返回:2.4.2.3 编码转换 调用ast_translate函数实现编码转换:3 T38 Asterisk支持pass-through方式T38传真,asterisk不发起reinvite,只是代理T38。 T38 reinvite经过asterisk时SDP协商的纠错方式,频率等信息可能被修改,T38包经过asterisk时UDPTLPacket被解析,具体T30内容不会被修改。 4 附录 4.1 文件流API 4.1.1 文件流操作函数 l struct ast_filestream *ast_readfile(const char *filename

14、, const char *type, const char *comment, int flags, int check, mode_t mode) 打开一个可读文件流,类似以只读方式fopen。 l struct ast_filestream *ast_writefile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode) 打开一个可写文件流,类似以写方式fopen。 l struct ast_frame *ast_readframe(struct a

15、st_filestream *s) 读取文件流数据,类似fread。 l int ast_writestream(struct ast_filestream *fs, struct ast_frame *f) 往文件流中写数据,类似fwrite如果读和写的格式不一致会调用ast_translate进行转换。 l int ast_closestream(struct ast_filestream *f) 关闭文件流,类似fclose。 4.1.2 文件流操作步骤 1. 打开可读文件流 (ast_readfile)或打开可写文件流(ast_writefile) 2. 读文件(ast_readfra

16、me)或写文件(ast_writestream) 3. 关闭文件流(ast_closestream) 4.1.3 文件流操作实例 见res_convert.c 把某种格式的文件转换成另外一种格式文件保存:static int cli_audio_convert(int fd, int argc, char *argv) int ret = RESULT_FAILURE; struct ast_filestream *fs_in = NULL, *fs_out = NULL; struct ast_frame *f; struct timeval start; int cost; char *f

17、ile_in = NULL, *file_out = NULL; char *name_in, *ext_in, *name_out, *ext_out; /* ugly, can be removed when CLI entries have ast_module pointers */ ast_module_ref(ast_module_info-self); if (argc != 4 | ast_strlen_zero(argv2) | ast_strlen_zero(argv3) ret = RESULT_SHOWUSAGE; goto fail_out; file_in = as

18、t_strdupa(argv2); file_out = ast_strdupa(argv3); if (split_ext(file_in, &name_in, &ext_in) ast_cli(fd, %s is an invalid filename!n, argv2); goto fail_out; /打开一个可读源文件流ext_in为输入文件格式 if (!(fs_in = ast_readfile(name_in, ext_in, NULL, O_RDONLY, 0, 0) ast_cli(fd, Unable to open input file: %sn, argv2); go

19、to fail_out; if (split_ext(file_out, &name_out, &ext_out) ast_cli(fd, %s is an invalid filename!n, argv3); goto fail_out; /打开一个可写目的文件流ext_out为输出文件格式 if (!(fs_out = ast_writefile(name_out, ext_out, NULL, O_CREAT|O_TRUNC|O_WRONLY, 0, 0644) ast_cli(fd, Unable to open output file: %sn, argv3); goto fail

20、_out; start = ast_tvnow(); while (f = ast_readframe(fs_in) /从源文件读取frame if (ast_writestream(fs_out, f) /向目的文件写frame如果读和写的格式不一致会调用ast_translate进行转换。 ast_cli(fd, Failed to convert %s.%s to %s.%s!n, name_in, ext_in, name_out, ext_out); goto fail_out; cost = ast_tvdiff_ms(ast_tvnow(), start); ast_cli(fd, Converted %s.%s to %s.%s in %dmsn, name_in, ext_in, name_out, ext_out, cost); ret = RESULT_SUCCESS; fail_out: if (fs_out) ast_closestream(fs_out); if (ret != R

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论