pjsip学习笔记

1、pjsip 是否采用 srtp 来传输媒体流是由两方面控制的:

(1)、pjsip是否支持 srtp 协议:

在 pjsua_call_media_init 中首先判断是采用 ICE 还是 UDP:

if (pjsua_var.media_cfg.enable_ice) {
	    status = create_ice_media_transport(tcfg, call_med, async);
            if (async && status == PJ_EPENDING) {
	        /* We will resume call media initialization in the
	         * on_ice_complete() callback.
	         */
                call_med->med_create_cb = &call_media_init_cb;
                call_med->med_init_cb = cb;

	        return PJ_EPENDING;
	    }
	} else {
	    status = create_udp_media_transport(tcfg, call_med);
	}

在该函数最后调用 call_media_init_cb,而该函数中则会强制采用 SRTP 覆盖之前的设定:

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
    /* This function may be called when SRTP transport already exists
     * (e.g: in re-invite, update), don't need to destroy/re-create.
     */
    if (!call_med->tp_orig) {
	pjmedia_srtp_setting srtp_opt;
	pjmedia_transport *srtp = NULL;

	/* Check if SRTP requires secure signaling */
	if (acc->cfg.use_srtp != PJMEDIA_SRTP_DISABLED) {
	    if (security_level < acc->cfg.srtp_secure_signaling) {
		err_code = PJSIP_SC_NOT_ACCEPTABLE;
		status = PJSIP_ESESSIONINSECURE;
		goto on_return;
	    }
	}

	/* Always create SRTP adapter */
	pjmedia_srtp_setting_default(&srtp_opt);
	srtp_opt.close_member_tp = PJ_TRUE;

	/* If media session has been ever established, let's use remote's 
	 * preference in SRTP usage policy, especially when it is stricter.
	 */
	if (call_med->rem_srtp_use > acc->cfg.use_srtp)
	    srtp_opt.use = call_med->rem_srtp_use;
	else
	    srtp_opt.use = acc->cfg.use_srtp;

	status = pjmedia_transport_srtp_create(pjsua_var.med_endpt,
					       call_med->tp,
					       &srtp_opt, &srtp);
	if (status != PJ_SUCCESS) {
	    err_code = PJSIP_SC_INTERNAL_SERVER_ERROR;
	    goto on_return;
	}

	/* Set SRTP as current media transport */
	call_med->tp_orig = call_med->tp;
	call_med->tp = srtp;
    }
#else
    call_med->tp_orig = call_med->tp;
    PJ_UNUSED_ARG(security_level);
#endif


由此可见,要禁用 SRTP,则必须将宏定义 PJMEDIA_HAS_SRTP 删除或定义为 0。

(2)、在传输媒体流的时候是否使用 SRTP:

srtp->bypass_srtp 是控制是否采用 SRTP 来传输媒体流的变量。首先,stream.c 中的函数 put_frame_imp 调用 pjmedia_transport_send_rtp,该函数中的回调函数(即 stream->transport->op->send_rtp)指向 transport_srtp.c 中的 transport_send_rtp 函数。当srtp->bypass_srtp = 1 的时候,transport_srtp.c 中的 transport_send_rtp 函数调用 pjmedia_transport_send_rtp,而此时该函数中的回调函数(即 stream->transport->member_tp->op->send_rtp)指向的就是 transport_udp.c 中的 transport_send_rtp 函数。因此,这种情况下并没有采用 SRTP 来传输媒体流,此时与直接使用 UDP 传输等效。

 

2、SRTP bypass 模式接收到对方媒体数据后的回调:

首先,stream.c 文件中的 pjmedia_stream_create 函数调用 pjmedia_transport_attach,该函数中的回调函数(即 tp->op->attach)指向 transport_srtp.c 中的 transport_attach,并将 stream.c 文件中的 on_rx_rtp 作为收到媒体数据后的回调传下去。

然后,transport_srtp.c 文件中的 transport_attach 函数调用 pjmedia_transport_attach,该函数中的回调函数(即 srtp->member_tp->op->attach)指向 transport_udp.c 中的 transport_attach,并将 transport_srtp.c 文件中的 srtp_rtp_cb 作为收到媒体数据后的回调传下去。

这样,当 transport_udp.c 收到对方的媒体数据的时候就会去调用 transport_srtp.c 文件中的 srtp_rtp_cb,而 srtp_rtp_cb 则会调用 srtp->rtp_cb。srtp->rtp_cb 指向的则是 stream.c 中的 on_rx_rtp。

即收到对方媒体数据后最终调用的回调函数是 stream.c 中的 on_rx_rtp。

 

3、windows平台下的声音采集和播放:

 

功能实现函数所在文件调用函数
注册设备pjmedia_aud_subsys_initaudiodev.cpjmedia_endpt_create
初始化设备factory_initwmme_dev.cinit_driver
启动设备factory_create_streamwmme_dev.cpjmedia_aud_stream_create
启动媒体流stream_startwmme_dev.cpjmedia_aud_stream_start
声音采集wmme_dev_threadwmme_dev.c单独线程
声音播放wmme_dev_threadwmme_dev.c单独线程

“启动设备”阶段,factory_create_stream 调用 init_player_stream 创建声音回放的内核事件,调用 init_capture_stream 创建声音采集的内核事件,而 wmme_dev_thread 中对这些事件进行循环监听,监听到有内核事件发生(声音回放、采集或退出监听线程)后就执行该事件。

退出监听线程事件也是在 factory_create_stream 中创建的,相应代码为:

    /* Create the stop event */
    strm->thread_quit_event = CreateEvent(NULL, FALSE, FALSE, NULL);

退出监听线程事件的触发是在 stream_destroy 中完成的,相应代码为:

SetEvent(stream->thread_quit_event);


 

 

 


 

 

 

 

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
exosip和pjsip都是开源的VoIP协议栈。 exosip是eXtended Osip的缩写,是一个基于oSIP库的高级SIP协议栈,用于在基于SIP(Session Initiation Protocol)的通信系统中实现VoIP功能。它提供了面向对象的API,使开发者能够轻松地编写自己的SIP应用程序。exosip支持SIP标准中的大部分功能,例如会话建立、信令传输、媒体流传输等。通过exosip,开发者可以构建自己的VoIP应用程序,如IP电话、语音会议系统等。 pjsip是一个开源的多媒体通信库,它实现了IP电话、呼叫中心、音视频会议等功能。pjsip是基于SIP协议的,但它也支持其他常用的VoIP协议,如UDP、TCP、TLS、HTTP等。它提供了完整的SIP协议栈和相关的音视频引擎,以及接口和工具,便于开发者使用。pjsip具有良好的跨平台性,可以在多种操作系统上运行,包括Windows、Linux、Android、iOS等。 exosip和pjsip都是基于开源的oSIP库开发的,但它们的主要区别在于功能和用途。exosip更偏向于提供高级的SIP协议栈,支持各种SIP标准功能的开发,适用于构建复杂的SIP应用程序。而pjsip则更多地提供了一个完整的VoIP通信库,包括SIP协议、音视频通信引擎等,适用于开发各种类型的VoIP应用。 总的来说,exosip和pjsip都是非常有用的开源VoIP协议栈,可以帮助开发者快速构建各种VoIP应用程序,提供灵活的通信解决方案。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值