视频拉取,指的是P1拉取P2的摄像头的视频,但是P2是不知道的。
使用Pjsip实现端到端的视频拉取,指的是P1通过拨打视频电话方式和P2通信,但是P2并没有通话的提示,也不用接听动作,P1就可以查看P2摄像头录像的视频,而且只能P1查看P2摄像头的视频和声音,P2是无法查看和听到P1的视频和声音的,说白了就是视频和声音是P2--->P1的单项传输。不过怎么区别普通的视频通话和拉取视频通话呢?这就是下面要说明的。
- 在sip头加入Pll字段,说明是否是视频拉取
- 修改sdp中传输方向
1. Java层
1.1 定义视频拉取通话接口
在PjsipCall中定义视频拉取接口public boolean makePullVideoCall(String buddyAccount)。
接口实现时,相比普通视频通话需要增加下面的参数定义:
1) 呼叫参数CallSetting中增加一个Flag定义,参数为64,csetting.setFlag(64);这个flag是c层pjsua_call_make_call函数中pjsua_call_setting参数的flag。
2) 增加sip协议头中Pll的定义:Pll为Pull的缩写,值为1说明是视频拉取
sipHeader.setHName("Pll");
sipHeader.setHValue("1");
1.2 定义音频拉取通话接口
在PjsipCall中定义视频拉取接口public boolean makePullAudioCall (String buddyAccount)。
接口实现时,相比普通视频通话需要增加下面的参数定义:
1) 呼叫参数CallSetting中增加一个Flag定义,参数为64,csetting.setFlag(64);这个flag是c层pjsua_call_make_call函数中pjsua_call_setting参数的flag。
2) 增加sip协议头中Pll的定义:Pll为Pull的缩写,值为1说明是视频拉取
sipHeader.setHName("Pll");
sipHeader.setHValue("1");
2. C层
2.1 pjsua_call结构体中添加isPull定义
修改位置:pjsip/include/pjsua-lib/pjsua_internal.h
在struct pjsua_call结构体中新增isPull成员变量,变量类型pj_bool_t类型
2.2 修改pjsua_media_channel_create_sdp函数
函数位置:pjsip/src/pjsua-lib/pjsua_media.c
修改函数中pjmedia_endpt_create_audio_sdp和pjmedia_endpt_create_video_sdp这两个函数的调用。把call->opt.flag参数传入,原始调用中,option参数只传0。
2.3 修改pjmedia_endpt_create_audio_sdp
函数位置:pjmedia/src/pjmedia/endpoint.c
在文件头中增加static const pj_str_t STR_RECVONLY = { "recvonly", 8 }; //added by dengfei的定义
把函数中status = init_sdp_media(m, pool, &STR_AUDIO, si);的调用,修改成:status = init_sdp_media_with_flag(m, pool, options, &STR_AUDIO, si);的调用。init_sdp_media_with_flag的实现后面
2.4 修改pjmedia_endpt_create_video_sdp
函数位置:pjmedia/src/pjmedia/endpoint.c
在文件头中增加static const pj_str_t STR_RECVONLY = { "recvonly", 8 }; //added by dengfei的定义(前面已经增加,就可以不用再增加了)
把函数中status = init_sdp_media(m, pool, &STR_AUDIO, si);的调用,修改成:status = init_sdp_media_with_flag(m, pool, options, &STR_AUDIO, si);的调用。init_sdp_media_with_flag的实现后面
2.5 新增函数定义init_sdp_media_with_flag
函数位置:pjmedia/src/pjmedia/endpoint.c
函数的实现,基本等同于init_sdp_media,只是在attr->name赋值时,需要根据option的值,判断是否是视频拉取。Option的值,就是java层中CallSetting定义的64的值。
修改如下:
if (flg & 64/*PJSUA_CALL_PULL_MEDIA*/) {
attr->name = STR_RECVONLY;
} else {
attr->name = STR_SENDRECV;
}
2.6 新增函数定义verify_pull_mode_incoming_request
函数位置:pjsip/src/pjsua-lib/pjsua_call.c
该函数用于在pjsua_call_on_incoming函数中,判断sip协议头是否携带Pll的定义,和取值,并修改pjsua_call结构体中isPull的取值。
2.7 call.hpp增加pullState值
在call.hpp的CallInfo中,增加pullState的定义。
2.8 pjsua_call_info增加isPull定义
修改位置:pjsip/include/pjsua-lib/pjsua.h
在pjsua.h的pjsua_call_info中,增加isPull的定义,代码如下:
/** is pull vide or audio call */
pj_bool_t isPull;
2.9 call.cpp增加pullState的赋值
在call.cpp的void CallInfo::fromPj(const pjsua_call_info &pci)中,增加pullState = PJ2BOOL(pci.isPull);赋值,这样java层就的callInfo就可以正常的获取到值。
2.10 pjsua_call_get_info函数中isPull的赋值
在pjsua_call.c的pjsua_call_get_info函数增加如下代码:
/*is pull video or audio call*/
info->isPull = call->isPull;
3. 修改默认视频的分辨率
1) 修改pjmedia/src/pjmedia-videodev/android_dev.c中的
#define DEFAULT_WIDTH 640//352
#define DEFAULT_HEIGHT 480//288
2) 修改pjmedia/src/pjmedia-codec/openh264.cpp中
# define DEFAULT_WIDTH 640//352
# define DEFAULT_HEIGHT 480//288
注意:这个了两个文件要同时修改才能生效
4. SDP中direction的协商
代码位置:pjmedia/src/pjmedia/sdp_neg.c
函数:update_media_direction
如果remote的direction为recvonly,local的direction就更改为sendonly