VoIP流媒体分析:MEDIASTREAMER2详解与优化

5星 · 超过95%的资源 需积分: 50 51 下载量 5 浏览量 更新于2024-07-27 1 收藏 680KB DOC 举报
本篇文章主要对MEDIASTREAMER2进行深入的分析研究,这是一个专注于VOIP(Voice over IP)领域中的流媒体处理引擎,用于实现在企业通讯客户端中的软电话功能,支持内外部电话间的通信、不同办公地点的音视频传输以及语音邮件等。文章详细介绍了MEDIASTREAMER2的架构、功能模块、编译流程、二次扩展以及关键的数据结构和API。 1. **目的**:文章的核心目标是理解MEDIASTREAMER2在VOIP中的应用,特别是如何优化音视频编码,提升通话质量和多媒体传输效率。通过对开源代码的深入分析,开发者可以了解到如何在实际项目中进行功能定制和性能优化。 2. **总体架构**: - **概述**:文章首先给出了一个整体的概念,强调了MEDIASTREAMER2在通信系统中的位置,以及它如何作为连接点处理音频、视频的编码和解码,以及RTP(Real-time Transport Protocol)的发送和接收。 - **功能模块**:详细列举了各项功能,包括注册FILTER(过滤器)、FILTERLink/执行、循环执行FILTER、编解码 FILTER(针对音频和视频)、音视频播放和捕获,以及ORTP(Open Real-Time Protocol)的功能描述。 3. **程序运行逻辑**: - MEDIASTREAMER2负责管理和调度各种FILTER的执行,确保音视频数据的实时传输。 - ORTP则涉及网络传输层,处理RTP协议相关的任务。 4. **编译流程**: - 文章指导读者如何在特定平台上编译,包括依赖的软件环境和编译设置,便于开发者在自己的环境中复制和调试。 5. **二次扩展**: - 提供了关于功能修改、编解码扩展(如对ORTP和MEDIASTREAMER2的自定义)、插件扩展以及遵循的函数接口标准,帮助用户根据需求扩展系统的能力。 6. **数据结构**: - 文档详细阐述了框架数据结构,包括函数指针、MSFilterDesc、MSFilter等核心数据结构,以及传输数据结构,这些对于理解和修改代码至关重要。 7. **API描述**: - 详尽地介绍了传输API、语音控制API、视频控制API、编解码API以及FILTER管理API,这些都是开发者操作和交互媒介流的关键接口。 8. **与其他技术的集成**:讨论了如何将MEDIASTREAMER2与SIP(Session Initiation Protocol)集成,以及它向界面提供的控制函数。 9. **应用场景**:最后,文章强调了MEDIASTREAMER2在实现企业内部通信、远程协作以及语音邮件等场景中的作用。 通过对这些内容的深入学习,读者可以全面理解MEDIASTREAMER2的工作原理,掌握如何定制化它以满足特定的音视频传输需求,并在实际开发中优化通话质量和多媒体体验。
2018-05-28 上传
首先接到这一个项目,说是要用mediastreamer2做一个网络电话。之前也是从来没有接触过。于是首先开始在百度中搜索一下需要哪些东西,以及那些步骤。最后大致了解了一下,做这个项目最终要的就是需要移植好多的库,每一个库都需要配置,最后在交叉编译好动态库,然后在执行mediastreamer2的时候去调用这些动态库和头文件就OK了。 1、首先meidastream2是基于ortp库的,那么首先就是下载源码,交叉编译。 交叉编译ortp 下载源码:http://savannah.c3sl.ufpr.br/linphone/ortp/sources/?C=S;O=A 我使用0.18.0版本 ortp-0.18.0.tar.gz 然后通过winshare(Windows和Linux的通信)把下载好的库文件拷贝到Linux下, 然后解压 tar zxvf ortp-0.18.0.tar.gz 注意这个时候可能会发生错误,是没有权限的问题,那么就在命令行前边加上sudo 然后配置 把下边这三行写成一个脚本 vim **.sh ./configure CC=arm-linux-gcc --host=arm-linux --target=arm-linux --prefix=/home/protocol_stack/install/ make make install 然后用chmod 777 **.sh 执行脚本./**.sh 这样子就完成了配置,编译,安装。(安装目录为/home/protocol_stack/install/,也就是最后生成的头文件,可执行文件,库文件都会在这个目录下) 2、因为项目是要用到SIP协议的,所以我们还需要移植sip的库 osip2和eXosip2协议,这两个协议对应两个库,osip是简单的osip协议,但是因为API少等一系列原因,增加了eXosip2对osip2的补充。 交叉编译osip2 下载源码:http://ftp.gnu.org/gnu/osip/ 我使用的版本是3.6.0 libosip2-3.6.0.tar.gz 然后通过winshare(Windows和Linux的通信)把下载好的库文件拷贝到Linux下, 然后解压 tar zxvf libosip2-3.6.0.tar.gz 注意这个时候可能会发生错误,是没有权限的问题,那么就在命令行前边加上sudo 然后配置 把下边这三行写成一个脚本 vim **.sh ./configure --host=arm-linux --target=arm-linux --prefix=/home/protocol_stack/install/ make make install 然后用chmod 777 **.sh 执行脚本./**.sh 交叉编译eXosip2 下载源码:http://ftp.gnu.org/gnu/osip/ 我使用的版本是3.6.0 libeXosip2-3.6.0.tar.gz 然后通过winshare(Windows和Linux的通信)把下载好的库文件拷贝到Linux下, 然后解压 tar zxvf libeXosip2-3.6.0.tar.gz 注意这个时候可能会发生错误,是没有权限的问题,那么就在命令行前边加上sudo 然后配置 把下边这三行写成一个脚本 vim **.sh ./configure --host=arm-linux --target=arm-linux --prefix=/home/protocol_stack/install/ PKG_CONFIG_PATH=/home/protocol_stack/install/lib/pkgconfig make make install 然后用chmod 777 **.sh 执行脚本./**.sh 接下来可以编译mediastreamer2了,不过ms2,依赖好多库:ogg、speex、pulseaudio。而pulseaudio又依赖许多库:alsa、json、libtool。 3、交叉编译ogg 下载源码:http://xiph.org/downloads/ 我使用1.3.1版本 libogg-1.3.3.tar.gz 然后通过winshare(Windows和Linux的通信)把下载好的库文件拷贝到Linux下, 然后解压 tar zxvf libogg-1.3.3.tar.gz 注意这个时候可能会发生错误,是没有权限的问题,那么就在命令行前边加上sudo 然后配置 把下边这三行写成一个脚本 vim **.sh ./configure CC=arm-linux-gcc --prefix=/home/protocol_stack/install/ --host=arm-linux make make install 然后用chmod 777 **.sh 执行脚本./**.sh 4、交叉编译speex 下载源码:http://www.speex.org/downloads/ 我使用1.2rc1版本 speex-1.2rc1.tar.gz 然后通过winshare(Windows和Linux的通信)把下载好的库文件拷贝到Linux下, 然后解压 tar zxvf speex-1.2rc1.tar.gz 注意这个时候可能会发生错误,是没有权限的问题,那么就在命令行前边加上sudo 然后配置 把下边这三行写成一个脚本 vim **.sh ./configure CC=arm-linux-gcc --prefix=/home/protocol_stack/install/ --with-ogg=/home/protocol_stack/install/ --enable-fixed-point --disable-float-api \ --host=arm-linux make make install 然后用chmod 777 **.sh 执行脚本./**.sh 5、交叉编译pulseaudio 下载源码:http://freedesktop.org/software/pulseaudio/releases/ 我使用1.0版本 pulseaudio-1.0.tar.gz 然后通过winshare(Windows和Linux的通信)把下载好的库文件拷贝到Linux下, 然后解压 tar zxvf pulseaudio-1.0.tar.gz 注意这个时候可能会发生错误,是没有权限的问题,那么就在命令行前边加上sudo 然后配置 把下边这三行写成一个脚本 vim **.sh ./configure CC=arm-linux-gcc CXX=arm-linux-g++ --prefix=/home/protocol_stack/install --host=arm-linux --disable-rpath --disable-nls --disable-dbus --disable-bluez --disable-samplerate --disable-solaris --disable-gconf --disable-avahi --disable-jack --disable-lirc --disable-glib2 --disable-gtk2 --disable-openssl --disable-ipv6 --disable-asyncns --disable-per-user-esound-socket --disable-oss-output --disable-oss-wrapper --disable-x11 --enable-neon-opt=no --with-database=simple PKG_CONFIG_PATH=/home/protocol_stack/install/lib/pkgconfig CPPFLAGS=-I/home/protocol_stack/install/include LDFLAGS=-L/home/protocol_stack/install/lib CFLAGS=-I/home/protocol_stack/install/include make make install 然后用chmod 777 **.sh 执行脚本./**.sh 错误1: checking for ltdl.h... no configure: error: Unable to find libltdl version 2. Makes sure you have libtool 2.4 or later installed. make: *** No targets specified and no makefile found. Stop. 分析;找不到libltdl。确保你有libtool 2.4及以上的版本。 下载libtool 2.4.2版本 这时需要交叉编译libtool 下载源码:ftp://ftp.gnu.org/gnu/libtool/ 我使用2.4.2版本 libtool-2.4.2.tar.gz 然后通过winshare(Windows和Linux的通信)把下载好的库文件拷贝到Linux下, 然后解压 tar zxvf libtool-2.4.2.tar.gz 注意这个时候可能会发生错误,是没有权限的问题,那么就在命令行前边加上sudo 然后配置 把下边这三行写成一个脚本 vim **.sh ./configure --host=arm-linux --prefix =/home/protocol_stack/install/ make make install 然后用chmod 777 **.sh 执行脚本./**.sh 交叉编译alsa: http://www.alsa-project.org/main/index.php/Main_Page 这个库的版本需要根据你嵌入式Linux内核中alsa的版本而定,可以使用命令查看内核中alsa的版本: # cat /proc/asound/version Advanced Linux Sound Architecture Driver Version 1.0.24. 可以到内核中alsa驱动版本是1.0.24,所以我选1.0.24版本 alsa-lib-1.0.24.1.tar.gz 然后通过winshare(Windows和Linux的通信)把下载好的库文件拷贝到Linux下, 然后解压 tar zxvf speex-1.2rc1.tar.gz 注意这个时候可能会发生错误,是没有权限的问题,那么就在命令行前边加上sudo 然后配置 把下边这三行写成一个脚本 vim **.sh ./configure --host=arm-linux --prefix =/home/protocol_stack/install/ make make install 然后用chmod 777 **.sh 执行脚本./**.sh 错误:configure: error: Package requirements ( sndfile >= 1.0.20 ) were not met: No package 'sndfile' found 分析:缺少库 libsndfile库,那么接下来再进行交叉编译libsndfile libsndfile-1.0.25.tar.gz http://www.linuxfromscratch.org/blfs/view/svn/multimedia/libsndfile.html 然后通过winshare(Windows和Linux的通信)把下载好的库文件拷贝到Linux下, 然后解压 tar zxvf libsndfile-1.0.25.tar.gz 注意这个时候可能会发生错误,是没有权限的问题,那么就在命令行前边加上sudo 然后配置 把下边这三行写成一个脚本 vim **.sh ./configure --host=arm-linux --prefix =/home/protocol_stack/install/ make make install 然后用chmod 777 **.sh 执行脚本./**.sh 7、最后编译mediastreamer2 下载源码:http://ftp.twaren.net/Unix/NonGNU//linphone/mediastreamer/ 我使用2.8版本 mediastreamer-2.8.0.tar.gz 然后通过winshare(Windows和Linux的通信)把下载好的库文件拷贝到Linux下, 然后解压 tar zxvf mediastreamer-2.8.0.tar.gz 注意这个时候可能会发生错误,是没有权限的问题,那么就在命令行前边加上sudo 然后配置 把下边这三行写成一个脚本 vim **.sh ./configure CC=arm-linux-gcc --prefix=/home/protocol_stack/install/ PKG_CONFIG_PATH=/home/protocol_stack/install/lib/pkgconfig --disable-gsm --enable-video=no --enable-macsnd=no --disable-static --disable-sdl --disable-x11 --disable-ffmpeg --host=arm-linux --target=arm-linux make make install 然后用chmod 777 **.sh 执行脚本./**.sh 上面的configure选项没有屏蔽v4l1和v4l2,所以还得交叉编译v4l 编译v4l libv4l-0.6.4.tar.gz 下载源码:http://pkgs.fedoraproject.org/repo/pkgs/libv4l/ 然后通过winshare(Windows和Linux的通信)把下载好的库文件拷贝到Linux下, 然后解压 tar zxvf libv4l-0.6.4.tar.gz 注意这个时候可能会发生错误,是没有权限的问题,那么就在命令行前边加上sudo 然后配置 我使用0.6.4版本 libv4l-0.6.4.tar.gz make clean make CC=arm-linux-gcc make install PREFIX=/home/protocol_stack/install 编译mediastreamer2出错:(1)checking for LIBCHECK... no checking for LIBJSON... no configure: error: Package requirements ( json >= 0.9 ) were not met: No package 'json' found 解决方法就是交叉编译json 下载源码:http://ftp.debian.org/debian/pool/main/j/json-c/ 分析:缺少json库,那么我们继续交叉编译json库 json-c_0.12.1.orig.tar.gz 然后通过winshare(Windows和Linux的通信)把下载好的库文件拷贝到Linux下, 然后解压 tar zxvf mediastreamer-2.8.0.tar.gz 注意这个时候可能会发生错误,是没有权限的问题,那么就在命令行前边加上sudo 然后配置 ./configure --host=linux-arm \ --prefix =/home/protocol_stack/install/ make && make install 好了,json库已经编译完成了。接下来我们继续编译mediastreamer2 。。。。。 但是还是有问题,怎么办呢?还是哪个问题还是找不到json库。 分析:在json的论坛中,找到了解决方案:把编译生成的/lib/pkgconfig/这个目录下生成了一个json-c.pc。最后mediastreamer2在调用的时候找的是json.pc。那么我们就把这个文件名改为json.pc #mv json-c.pc json.pc OK,这次这个是可以编译的过去了。接下来继续编译 。。。 又出现问题了 /home/protocol_stack/install/lib/libjson.so: undefined reference to `rpl_malloc' /home/protocol_stack/install/lib/libjson.so: undefined reference to `rpl_realloc' 问题分析: 这个错误的原因是因为没有定义 rpl_malloc 和 rpl_realloc 这两个变量。 那么我们应该怎么办么? 那么就在这个目录下进行查这两个变量是在哪里定义的? 于是:#grep "rpl_malloc" -nR * ....... 找到了,原来这两个变量是在这个config的文件中的。是一个宏开关 那么就好办了,我们就直接把这两个宏进行注释。 嗯嗯,继续。。。我们重新编译json库。。。嗯嗯编译好了,接下来继续来编译mediastreamer2 。。。。 又出错了,还是这个原因 /home/protocol_stack/install/lib/libjson.so: undefined reference to `rpl_malloc' /home/protocol_stack/install/lib/libjson.so: undefined reference to `rpl_realloc 嗯嗯,还是这个原因?究竟是为什么呢。再次来到json的目录下,再次看有没有把那两个宏开关给关闭? 嗯哼? 竟然没有关闭? 分析?明白了。原来是我把配置和编译同时执行了。这个宏开关是./configure ...生成的。 那么就只好,这样。把./configure。。。生成的config文件,再进行关闭宏开关。最后直接make && make install -j8 直接编译,安装,是不能再次进行配置的。因为以配置config文件就会再次生成,那么宏开关就又开了。 OK,安装好了,下来继续进行编译mediastreamer2.。。。。。。。。。。。 。。。。。。。。。。。。。。 又出现了问题? error: /user/include/python2.7/pyconfig.h:15:52: fatal error: arm-linux-gnueabi/python2.7/pyconfig.h: No such file or directory compilation terminated. 分析::找不到arm-linux-gnueabi/python2.7/pyconfig.h这文件。那就继续交叉编译python 好吧,继续下载python,然后再进行交叉编译,但是编译Python的时候出来一系列的问题。根本没有办法解决。 那么该怎么办呢?时候一个小时又一个小时的过去? 最后有一个大胆的想法,既然python都编译不下去。那就不要了。 于是,在mediastreamer2的./configure 中添上一项 --without-python 。 。。。再次配置编译。。。。。。。。。。。 error: /user/include/python2.7/pyconfig.h:15:52: fatal error: arm-linux-gnueabi/python2.7/pyconfig.h: No such file or directory compilation termiated. 嗯哼?还是一样的错误。怎么办呢? 于是乎就又在论坛上进行找灵感。。。。。 还是找不到。。。 又一结合前边几个库的配置编译,发现不使能一个模块还可以用另外一个--disable-python 。。。 于是乎 就把--without-python改为了--disable-python 继续编译。。。。 。。。。。。。。。。。。。。。。。。。。。 到了这个节骨眼上了,编译每跳一下,我的心就跟着逗一下。。。。心酸 。。。。。。 。。。。。。 。。。。。。 竟然编译成功了。。。。 哈哈。。。。。。。。。 于是,马上就把编译好的库,拷贝到了开发板。。。 嗯嗯,本来还想把编译好的库目录树拷贝下的,但是太多了,放不下。。。算了吧。。。。 找到编译好的库 在库中的/bin中找到arm-linux-mediastream 然后执行./arm-linux-mediastream 。。。。报错了 问题: error : while loading shared libraries: libmediastreamer.so.1: cannot open shared object file: No such file 答案:分析: 遇到这个问题就是,libmediastreamer.so.1这个动态库,在可执行文件armlinuxmediastreamer执行的时候,会调用这个动态库,但是环境变量中找不到这个动态库。那么我们就是要把我们编译好的动态链接库的目录加到环境变量中 LD_LIBRARY_PATH=$LD_LIBRARY_PATH://arm/lib/这个目录下就是放着我们编译好的所有的动态链接库(包括libmediastreamer.so.1) 执行步骤:LD_LIBRARY_PATH=$LD_LIBRARY_PATH://arm/lib export LD_LIBRARY_PATH ./arm-linux-mediastream mediastream --local --remote --payload [ --fmtp ] [ --jitter ] [ --width ] [ --height ] [ --bitrate ] [ --ec (enable echo canceller) ] [ --ec-tail ] [ --ec-delay ] [ --ec-framesize ] [ --agc (enable automatic gain control) ] [ --ng (enable noise gate)] [ --ng-threshold (noise gate threshold) ] [ --ng-floorgain (gain applied to the signal when its energy is below the threshold.) ] [ --capture-card ] [ --playback-card ] [ --infile <input wav file> specify a wav file to be used for input, instead of soundcard ] [ --outfile specify a wav file to write audio into, instead of soundcard ] [ --camera ] [ --el (enable echo limiter) ] [ --el-speed (gain changes are smoothed with a coefficent) ] [ --el-thres (Threshold above which the system becomes active) ] [ --el-force (The proportional coefficient controlling the mic attenuation) ] [ --el-sustain (Time in milliseconds for which the attenuation is kept unchanged after) ] [ --el-transmit-thres (TO BE DOCUMENTED) ] [ --rc (enable adaptive rate control) ] [ --zrtp (enable zrtp) ] [ --verbose (most verbose messages) ] [ --video-windows-id <video surface:preview surface>] [ --srtp (enable srtp, master key is generated if absent from comand line) [ --netsim-bandwidth (simulates a network download bandwidth limit) 于是按照第一种方式进行 参数添加 ./arm-linux-mediastream --local 8888 --remote 127.0.0.1:88 88 OK运行正常了 下面是运行信息。。。 ortp-message-audio_stream_process_rtcp: interarrival jitter=119 , lost packets percentage since last report=0.000000, round trip time=0.000000 seconds ortp-message-oRTP-stats: RTP stats : ortp-message- number of rtp packet sent=150 ortp-message- number of rtp bytes sent=25800 bytes ortp-message- number of rtp packet received=150 ortp-message- number of rtp bytes received=25800 bytes ortp-message- number of incoming rtp bytes successfully delivered to the application=25284 ortp-message- number of rtp packet lost=0 ortp-message- number of rtp packets received too late=0 ortp-message- number of bad formatted rtp packets=0 ortp-message- number of packet discarded because of queue overflow=0 ortp-message-Bandwidth usage: download=81.290281 kbits/sec, upload=81.288664 kbits/sec ortp-message-Receiving RTCP SR ortp-message-Receiving RTCP SDES ortp-message-Found CNAME=unknown@unknown ortp-message-Found TOOL=oRTP-0.18.0 ortp-message-Found NOTE=This is free sofware (LGPL) ! ortp-message-Quality indicator : 4.888437 运行正常了。。。。。。