PJMEDIA PORT 的概念

媒体端口(Media Port)提供抽象和可扩展的框架(framework)来实现媒体端点。基本上,媒体端口接口有以下属性:

--媒体端口属性信息(pjmedia_port_info):描述媒体端口的属性,如采样频率(sampling rate)、通道数量(number of channels)等。

--指向从媒体端口获取语音帧的get_frame函数指针,这个函数将由公共API函数pjmedia_port_get_frame()调用。

--指向向媒体端口发送语音帧的put_frame函数指针,这个函数将由公共API函数pjmedia_port_put_frame()调用。

 

媒体端口都是被动"对象",应用程序或其他PJMEDIA组件必须手动调用pjmedia_port_get_frame()和pjmedia_port_put_frame()来从这个对象中获取或向这个对象发送语音帧。

 

一些媒体端口,如PJMEDIA_CONF、PJMEDIA_RESAMPLE_PORT可以从内部相互连接,而另一些端口代表语音帧的最终接收者或最初的发送者(终结者或始作者)。

 

例如,假设应用程序想一个WAV文件的采样频率转换为另一个频率,则应该创建并按照以下方式安排端口的连接:

 

应用程序使用下面的伪代码创建并设置媒体端口:

 

      pjmedia_port *player, *resample, *writer;
      pj_status_t status;
 
      // Create the file player port.
      status = pjmedia_wav_player_port_create(pool, 
                                           "Input.WAV",     // file name
                                           20,      // ptime.
                                           PJMEDIA_FILE_NO_LOOP, // flags
                                           0,      // buffer size
                                           NULL,      // user data.
                                           &player );
      PJ_ASSERT_RETURN(status==PJ_SUCCESS, PJ_SUCCESS);
 
      // Create the resample port with specifying the target sampling rate,
      // and with the file port as the source. This will effectively
      // connect the resample port with the player port.
      status = pjmedia_resample_port_create( pool, player, 8000,
                                          0, &resample);
      PJ_ASSERT_RETURN(status==PJ_SUCCESS, PJ_SUCCESS);
 
      // Create the file writer, specifying the resample port's configuration
      // as the WAV parameters.
      status pjmedia_wav_writer_port_create(pool,
                                            "Output.WAV",  // file name.
                                            resample->info.clock_rate,
                                            resample->info.channel_count,
                                            resample->info.samples_per_frame,
                                            resample->info.bits_per_sample,
                                            0,  // flags
                                            0,  // buffer size
                                            NULL, // user data.
                                            &writer);

 

设置完成后,应用程序可以运行下面的循环来执行转换过程:

 

   pj_int16_t samplebuf[MAX_FRAME];
   
   while (1) {
       pjmedia_frame frame;
       pj_status_t status;
 
       frame.buf = samplebuf;
       frame.size = sizeof(samplebuf);
 
       // Get the frame from resample port.
       status = pjmedia_port_get_frame(resample, &frame);
       if (status != PJ_SUCCESS || frame.type == PJMEDIA_FRAME_TYPE_NONE) {
             // End-of-file, end the conversion.
              break;
       }
 
       // Put the frame to write port.
       status = pjmedia_port_put_frame(writer, &frame);
       if (status != PJ_SUCCESS) {
             // Error in writing the file.
             break;
       }
   }

 

完成转换后,应用程序要销毁媒体端口:

 // Note: by default, destroying resample port will destroy the
 //  the downstream port too.
   pjmedia_port_destroy(resample);
   pjmedia_port_destroy(writer);

 

对于这个简单的WAV文件采样频率转换的例子,以上步骤就足够了。但是其他更为复杂的目的,读和写语音帧的过程可能需要以定时的方式进行,例如发送RTP包到一个远程的流对象。更进一步,随着应用程序规模的逐渐增大,手动读写语音帧的操作越来越频繁,如果PJMEDIA提供自动处理这个过程的机制,这样可能会更好。 

 

事实上,PJMEDIA已经提供了使媒体流在媒体端口之间自动地流动的机制,在PJMEDIA_PORT_CLOCK 节描述这样的机制。
  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值