现在的位置: 首页 > 综合 > 正文

mediastreamer2的使用

2013年08月02日 ⁄ 综合 ⁄ 共 4375字 ⁄ 字号 评论关闭

mediastreamer2是一个功能强大且小巧的流引擎,专门为视频电话应用而开发的。为linphone中所有的接收、发送多媒体流提供处理,包括音频视频捕捉、编码、解码、渲染。

Filter: 媒体库中处理数据的组件。一个filter有0到数个输入流和0到数个输出流。

filter的作用:在mediastreamer2里面是MSFilter,可以利用MSFilter实现下面的应用,实例参见/mediastreamer2/tests/:

      捕获音频或者视频数据.、播放音频或者显示视频数据.、发送或者接受RTP数据.、对音频或者视频数据的编解码、变化 (视频大小调整, 音频取样等等) 数据、 复制数据.、混和音频视频数据.

graph的作用:是管理几个连接在一起的filter的组件. 它能够把数据从输出流传输到输入流 并且负责管理这些filters

最简单的graph 例子:AUDIO CAPTURE (FILTER)  -->   ENCODE (FILTER) -->     RTP(FILTER)

      上面的graph 由三个 filters组成. Audio capture filter没有输入,直接从驱动捕获音频数据然后提供给输出流. 然后把输出流连接到encoder
filter 的输入流上,coder filter 把这些音频数据进行编码以后然后送给输出流.最后把这个输出流连接到rtp filter的输入流上,然后由rtp filter把数据封装成rtp送出去。

       该模块的设计可以让应用开发者使用自己的encode/decode
filter 替代已有的"encode/decode filter" . 该媒体库支持g711u, g711a, h263的encode filter. 应用开发者也可以动态加入自己实现的encode filter,用来支持其他的编码格式。

如何使用媒体库?

    媒体库提供许多功能, 它主要用来管理RTP 音频和视频 会话.你将需要使用API函数创建filters,并且把它们连接进一个graph. 然后使用API函数能够用来启动和停止graph.

媒体库的初始化

     要使用媒体库, 首先需要对他进行初始化:

      ms_init();

媒体库提供许多filters. 这些filter必须被连接在一起以至一个filter的输出能够变成其他filter的输入.

通常, filters 被用来处理音频和视频数据. 他们能够捕获音频和视频数据,播放音频和视频数据, 对这些数据进行编解码, 合成这些数据 , 转换这些数据.最重要的filters 是RTP filters,他能够接收和发送RTP数据.

Graph的例子

要真正使用媒体库进行通话, 就必须构建两个graphs. 当然这两个graph都相当简单。

第一个graph需要三个filter,从声卡捕获数据,然后进行编码,最后把编码后的数据发送给RTP session.

             AUDIO    ->    ENCODER   ->   RTP

            CAPTURE   ->              ->  SENDER

第二个graph同样需要三个filter, 从一个RTP session接收数据,然后解码,最后把解码后的数据发送给播放设备.

        RTP      ->    DECODER   ->   AUDIO

       RECEIVER  ->              ->  PLAYBACK

初始化Graph的例子

为了便于阅读和理解,下面的代码没有差错检查.为了构造一个graph, 需要一些而外的输入输出设备:比如需要选择一个声卡用来捕获和播放音频,同时还需要使用创建一个RTP session用来发送和接受rtp流.

      MSSndCard *sndcard;

      sndcard=ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());

        /* audio capture filter */

      MSFilter *soundread=ms_snd_card_create_reader(captcard);

      MSFilter *soundwrite=ms_snd_card_create_writer(playcard);

      MSFilter *encoder=ms_filter_create_encoder("PCMU");

      MSFilter *decoder=ms_filter_create_decoder("PCMU");

      MSFilter *rtpsend=ms_filter_new(MS_RTP_SEND_ID);

      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);

      MSFilter *dtmfgen=ms_filter_new(MS_DTMF_GEN_ID);

大多数情况下上面的graph还是不够的: 通常还需要对filter进行一些配置. ,比如还需要设置声卡filters的取样率。

      int sr = 8000;

      int chan=1;

      ms_filter_call_method(soundread,MS_FILTER_SET_SAMPLE_RATE,&sr);

      ms_filter_call_method(soundwrite,MS_FILTER_SET_SAMPLE_RATE,&sr);

      ms_filter_call_method(stream->encoder,MS_FILTER_SET_SAMPLE_RATE,&sr);

      ms_filter_call_method(stream->decoder,MS_FILTER_SET_SAMPLE_RATE,&sr);

      ms_filter_call_method(soundwrite,MS_FILTER_SET_NCHANNELS, &chan);

      /* if you have some fmtp parameters (from SDP for example!)

      char *fmtp1 = ** get your fmtp line **;

      char *fmtp2 = ** get your fmtp line **;

      ms_filter_call_method(stream->encoder,MS_FILTER_ADD_FMTP, (void*)fmtp1);

      ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)fmtp2);

链接filters并且运行graph 的例子

      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->dtmfgen,0);

      ms_filter_link(stream->dtmfgen,0,stream->soundwrite,0);

按照上面的步骤链接后,还需要把这些filters配属给一个ticker. Ticker 是graph管理器,负责启动filters.

上面的例子里有两个graph, 我们需要把两个graph中没有输入流的filter配属给Ticker.

      /* create ticker */

      MSTicker *ticker=ms_ticker_new();

      ms_ticker_attach(ticker,soundread);

      ms_ticker_attach(ticker,rtprecv);

解除filters并且停止graph的例子

      ms_ticker_detach(ticker,soundread);

      ms_ticker_detach(ticker,rtprecv);

      ms_filter_unlink(stream->soundread,0,stream->encoder,0);

      ms_filter_unlink(stream->encoder,0,stream->rtpsend,0);

      ms_filter_unlink(stream->rtprecv,0,stream->decoder,0);

      ms_filter_unlink(stream->decoder,0,stream->dtmfgen,0);

      ms_filter_unlink(stream->dtmfgen,0,stream->soundwrite,0);

      if (rtp_session!=NULL) rtp_session_destroy(rtp_session);

      if (rtpsend!=NULL) ms_filter_destroy(rtpsend);

      if (rtprecv!=NULL) ms_filter_destroy(rtprecv);

      if (soundread!=NULL) ms_filter_destroy(soundread);

      if (soundwrite!=NULL) ms_filter_destroy(soundwrite);

      if (encoder!=NULL) ms_filter_destroy(encoder);

      if (decoder!=NULL) ms_filter_destroy(decoder);

      if (dtmfgen!=NULL) ms_filter_destroy(dtmfgen);

      if (ticker!=NULL) ms_ticker_destroy(ticker);

抱歉!评论已关闭.