基于android手机实时监控ipcam视频之二:mediastream2

本文介绍mediastream2框架如何实现从接收RTP媒体流到视频解码及在Android设备上显示的全过程。重点讲解了RTP接收、H.264解码及显示等关键filter的创建与配置。

    在项目中用到了mediastream2,mediastream2是一个框架,引擎,它驱动系统的整个流程,从接收rtp媒体流并解析到媒体解码到显示到android手机屏幕上,都是由mediastream2来驱动完成的。

    mediastream2是由一个个filter来完成,我们可以把filter当做一个单独的数据处理模块,它就像一个盒子,有输入和输出接口,数据从输入接口进来,处理完成后,再从输出接口出来进入到下一个filter中,多个filter连接在一起,就组成了一个系统循环。在我们的系统中,主要流程是ipcam发送rtp媒体流,系统接收rtp媒体流并解析,然后进行解码,再显示到android手机屏幕上,因此我们定义了三个filter,分别是:RTP Recv filter(RTP媒体流接收),Video Decoder filter(视频解码)和Android Display filter(视频输出显示),其基本流程如下:



                           RTP Recv----------------->Video Decoder------------------------------> Android Display


    首先我们要调用ms_init()这个函数,这个函数初始化mediastream2。

    void ms_init(){
int i;
MSSndCardManager *cm;


#if defined(ENABLE_NLS)
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
#endif


#if !defined(_WIN32_WCE)
if (getenv("MEDIASTREAMER_DEBUG")!=NULL){
ortp_set_log_level_mask(ORTP_DEBUG|ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
}
#endif
#ifdef ANDROID
ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
ortp_set_log_handler(ms_android_log_handler);
#endif
ms_message("Mediastreamer2 " MEDIASTREAMER_VERSION " (git: " GIT_VERSION ") starting.");
/* register builtin MSFilter's */
for (i=0;ms_filter_descs[i]!=NULL;i++){
ms_filter_register(ms_filter_descs[i]);
}
ms_message("Registering all soundcard handlers");
cm=ms_snd_card_manager_get();
for (i=0;ms_snd_card_descs[i]!=NULL;i++){
ms_snd_card_manager_register_desc(cm,ms_snd_card_descs[i]);
}


#ifdef VIDEO_ENABLED
ms_message("Registering all webcam handlers");
{
MSWebCamManager *wm;
wm=ms_web_cam_manager_get();
for (i=0;ms_web_cam_descs[i]!=NULL;i++){
ms_web_cam_manager_register_desc(wm,ms_web_cam_descs[i]);
}
}
#if !defined(NO_FFMPEG)
ms_ffmpeg_check_init();
__register_ffmpeg_encoders_if_possible();
#endif
#endif
#ifdef PACKAGE_PLUGINS_DIR
ms_message("Loading plugins");
ms_load_plugins(PACKAGE_PLUGINS_DIR);
#endif


#if defined(ANDROID) && defined (VIDEO_ENABLED)
if (1) {
libmsandroidopengldisplay_init();
} else {
if (!libmsandroiddisplay_init()) {
libmsandroiddisplaybad_init();
}
}
#endif
ms_message("ms_init() done");
}

    在这个函数里面,ms_filter_descs定义了目前支持的所有的filter,进一步分析

MSFilterDesc * ms_filter_descs[]={
&ms_alaw_dec_desc,
&ms_alaw_enc_desc,
&ms_ulaw_dec_desc,
&ms_ulaw_enc_desc,
&ms_rtp_send_desc,
&ms_rtp_recv_desc,
&ms_dtmf_gen_desc,
&ms_ice_desc,
&ms_tee_desc,
&ms_conf_desc,
&ms_join_desc,
&ms_volume_desc,
&ms_void_sink_desc,
//&ms_speex_dec_desc,
//&ms_speex_enc_desc,
//&ms_speex_ec_desc,
&ms_file_player_desc,
&ms_file_rec_desc,
//&ms_resample_desc,
&ms_equalizer_desc,
//&ms_gsm_enc_desc,
//&ms_gsm_dec_desc,
&ms_tone_detector_desc,
&ms_audio_mixer_desc,
&ms_g722_dec_desc,
&ms_g722_enc_desc,
#ifdef VIDEO_ENABLED
&ms_mpeg4_enc_desc,
&ms_mpeg4_dec_desc,
&ms_h263_enc_desc,
&ms_h263_dec_desc,
&ms_h264_dec_desc,
&ms_pix_conv_desc,
&ms_size_conv_desc,
//&ms_vp8_enc_desc,
//&ms_vp8_dec_desc,
#endif
NULL
};


我们可以看到系统定义了很多filter,比如ms_rtp_recv_desc是RTP接收filter,ms_h264_dec_desc是H.264解码filter等等。

MSFilterDesc ms_h264_dec_desc={
.id=MS_H264_DEC_ID,
.name="MSH264Dec",
.text="A H264 decoder based on ffmpeg project.",
.category=MS_FILTER_DECODER,
.enc_fmt="H264",
.ninputs=1,
.noutputs=1,
.init=dec_init,
.process=dec_process,
.uninit=dec_uninit,
.methods=h264_dec_methods
};


在filter定义里面,id是用来标示每个filter的唯一标示符;name是起得一个名称;text是描述,上面就表示该filter是基于ffmpeg的H.264解码;category是分类,有解码器,编码器和其它三种类型;enc_fmt表示媒体类型;ninputs表示input个数,可能每个filter有多个输入接口;noutputs表示输出接口;init定义初始化函数,在调用filter之前必须 调用;process是最核心的处理函数,filter从input端接收数据就调用该函数进行数据处理;uninit定义退出函数;methods表示额外定义的一些函数,使用这个接口可以对filter进行一些参数设置工作,比如在上面的h.264解码filter中定义了专门的函数用来设置h.264解码所需要的fmtp信息。除了mediastream2自带的这些filter以外,我们还可以自己定义filter,按照上面的格式来定义,然后通过ms_filter_register函数注册进来就可以使用了。在我们系统中我们使用ms_rtp_recv_desc来完成rtp的接收解析,使用ms_h264_dec_desc来完成视频解码,使用ms_android_opengl_display_desc来完成在android上的显示。

定义完成了3个filter,接收流,解码并显示,这三个filter是如何创建并连接在一起并工作起来呢?见下面的代码注释


MSConnectionHelper ch;
    /*根据ipcam video的codec来创建相应的解码器filter,创建失败,则退出,在我们系统里面一般是h.264,但我们可以根据rtp媒体类型在自适应选择对应的解码filter*/
    stream->decoder=ms_filter_create_decoder(ipcam_get_codec("video")); // 创建解码filter
    if (stream->decoder==NULL)
    {
        /* big problem: we don't have a registered decoderfor this payload...*/
        ms_error("videostream.c: No decoder available  ");
        return -1;
    }


    /*创建rtp接受filter*/
    stream->rtprecv = ms_filter_new (MS_RTP_RECV_ID);//创建RTP接收filter,通过MS_RTP_RECV_ID找到ms_rtp_recv_desc这个filter

   /*创建rtp接收filter,需要设置rtp接收filter的会话,会话主要是接收媒体流的socket,告诉filter再哪个socket上接收rtp数据,并限制接收什么样的rtp数据,通过payload type*/

/*stream->session这个是_RtpSession*, 是mediastream2定义的结构体*/
    ms_filter_call_method(stream->rtprecv,MS_RTP_RECV_SET_SESSION,stream->session);
    ms_message("ssap_ipcam_client_open:session rtpsocket=%d,rtcpsocket=%d",stream->session->rtp.socket,stream->session->rtcp.socket);


    /*创建output filter,默认是MSAndroidDisplay,表示输出到android上,通过MSAndroidDisplay找到ms_android_opengl_display_desc*/
    displayName = ms_strdup("MSAndroidDisplay");
    stream->output=ms_filter_new_from_name(displayName);


    /*以下是设置fmtp,非常重要,如果不添加fmtp,将会解码失败,mpeg4需要的fmtp在rtsp中是在sdp中
    带过来的,因此要获取fmtp*/
    char fmtp[1000];
    memset(fmtp,0,sizeof(fmtp));
    sprintf(fmtp,"config=%s",ipcam_get_fmtp("video"));
    ms_message("ipcam fmtp=%s",fmtp);
    ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)fmtp);
    format=MS_YUV420P;
    ms_filter_call_method(stream->decoder,MS_FILTER_SET_PIX_FMT,&format);


    int tmp;
    /*configure the display window */
    disp_size.width=MS_VIDEO_SIZE_CIF_W;
    disp_size.height=MS_VIDEO_SIZE_CIF_H;
    tmp=1;

/*设置一些参数,主要用来显示*/
    ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&disp_size);
    ms_filter_call_method(stream->output,MS_VIDEO_DISPLAY_ENABLE_AUTOFIT,&tmp);
    ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format);
    //ms_filter_call_method(stream->output,MS_VIDEO_DISPLAY_SET_LOCAL_VIEW_MODE,&stream->corner);


    if (stream->window_id != 0) 
    {
        ms_message("v2 sam display windows id=%d,stream=%p",stream->window_id,stream);
        /*设置显示的窗口id,在哪个窗口上显示video*/
        ms_filter_call_method(stream->output, MS_VIDEO_DISPLAY_SET_NATIVE_WINDOW_ID,stream->window_id);
    }


 /*以上完成了3个filter的创建,接下来将3个filter串联起来*/
    /* and connect the filters */
    ms_connection_helper_start (&ch);
    ms_connection_helper_link (&ch,stream->rtprecv,-1,0);
    ms_connection_helper_link (&ch,stream->decoder,0,0);


    ms_connection_helper_link (&ch,stream->output,0,-1);


  /*filter串联起来了以后,开始启动定时器,整个系统流程开始运转起来*/
    /* create the ticker */
    stream->ticker = ms_ticker_new();
    ms_ticker_set_name(stream->ticker,"Video MSTicker");
    /* attach the graphs */
    if (stream->source)
        ms_ticker_attach (stream->ticker, stream->source);
    if (stream->rtprecv)
        ms_ticker_attach (stream->ticker, stream->rtprecv);


至此,mediastream2就开始运转起来了

             

首先接到这一个项目,说是要用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 运行正常了。。。。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值