1.PJSIP源码探究 pjmedia-videodev模块
2.å¦ä½å¨ android 设å¤ä¸ä½¿ç¨ pjsip G.729 ç¼è§£ç çåè½
3.pjsip 本地视频预览怎么改变内容源的码目大小 iOS
PJSIP源码探究 pjmedia-videodev模块
PJMEDIA-Videodev模块详解:在PJSIP中的视频捕获功能实现
PJSIP中,pjmedia-videodev模块扮演着关键角色,码目它负责视频捕获功能,码目让开发者能够在应用中集成自定义画面捕获设备。码目为了深入了解,码目首先需要理解pjsua2中的码目会员项目源码工作流程,包括Endpoint对象的码目使用和相关c++函数的调用,如pjsua_create、码目pjsua_start和pjsua_init等。码目
在pjsip的码目源码中,视频捕获设备的码目初始化过程始于pjsua_media_subsys_init,这个函数通过pjsua_media_config_default参数,码目初始化了媒体子系统,码目其中包括视频和音频子系统。码目其中,码目pjmedia_vid_subsys_init在pjmedia-videodev模块的pjmedia_vid.c中被调用,用于初始化视频捕获设备子系统。
在Android环境下,pjmedia_and_factory是心率算法源码关键,它会在编译时根据平台特性注册到视频子系统中。当需要视频捕获时,会通过这个工厂创建具体设备,如摄像头,并获取画面。pjmedia-videodev-factory在android_dev.c文件中实现,包含了设备查找、参数设置和流创建等功能,如and_factory_init、能量公式源码and_factory_create_stream等。
视频流的管理主要通过pjmedia_vid_dev_stream结构体和对应的stream_op函数,如and_stream_get_param、and_stream_set_cap等,它们控制摄像头的设置和画面捕获。在自定义捕获中,可以通过这些接口添加时间水印,创造出更为丰富的视频体验。
总之,财富生肖源码pjmedia-videodev模块为PJSIP提供了灵活的视频捕获能力,开发者可以根据需求定制捕获设备和功能。理解并掌握这一模块的工作原理,将有助于在实际项目中实现个性化的视频通话体验。
å¦ä½å¨ android 设å¤ä¸ä½¿ç¨ pjsip G. ç¼è§£ç çåè½
第ä¸æ¥æ¯çæ pjsip 为 Android ï¼æ¥éª¤ä¸º Ubuntu Linuxï¼ çæºä»£ç ï¼
设置 ANDROID_NDK_ROOT ç¯å¢åéè®¾ç½®ä¸ºæ¨ NDK æ ¹æ件夹ã
è½¬å° pjsip 2.x æ件夹并å建 pjlib/include/pj/config_site.h å æ¬ config_site_sample.h ( #include <pj/config_site_sample.h> )
è¿è¡./configure-android
è¿è¡make clean && make depend && make
ä¹åè¿äºæ¥éª¤ï¼ä½ å°æå 个éæåºä¸çå 个æ件夹ãæ建议å°å®ä»¬åç»ç¸åçæ件夹 ï¼æ好å¨æ¨ç项ç®ä¸ï¼ ä¸çï¼
mkdir <your_project_path>/pjsip_libs
find . -name *.a | xargs -I % cp % <your_project_path>/pjsip_libs/
ä¸æ¦ä½ çææåºï¼æ¨éè¦å°è¿äºåºæ·»å å°æ¨çé¡¹ç® Android.mk æ件ï¼è¿æ¯ç±å æ¬ä¸ä¸ªæ°ç模åèæ¯ä¸ªå¾ä¹¦é¦ãæ¤æ¨¡åé¨ååºè¯¥æ¯ä¸æ ·çä¸è¥¿ï¼
include $(CLEAR_VARS)
LOCAL_MODULE := pjsua-arm-unknown-linux-androideabi
LOCAL_SRC_FILES := $(MY_PJLIB_PATH)/libpjsua-arm-unknown-linux-androideabi.a
include $(PREBUILT_STATIC_LIBRARY)
ï¼ä½ å ¶å®æ¯ä¸èä¸æ建æ¨ç JNI 项ç®çæºä»£ç ï¼ææ模åé½æ·»å å°æ¨çéæåºçå¼ç¨ï¼
LOCAL_STATIC_LIBRARIES := pjsua-arm-unknown-linux-androideabi ...
è¿å°å æ¬ pjsip çå¼ç¨å å ¥æ¨ç JNI åºãç°å¨ï¼æ¨éè¦é ç½® pjsip UA å®ä¾ã
ä½ æä¸ä¸ªå ³äº init åå¼å§ç解é pjsip ç UA (pjsua) å¨ pjsip/include/pjsua-lib/pjsua.h ä½è¦éµå¾ªç主è¦æ¥éª¤æ¯ï¼
å建ä¸ä¸ªå ·æ UA å®ä¾pjsua_create
å建ä¸ä¸ªå·¥ä½çº¿ç¨ä¸pj_thread_create
UA å®ä¾ç设置çé»è®¤é ç½®ï¼
pjsua_config cfg æ¡© ï¼pjsua_logging_config log_cfg ï¼pjsua_media_config media_cfg ï¼
pj_cli_cfg_default(&app_config.cli_cfg.cfg) ï¼pjsua_logging_config_default(&log_cfg) ï¼pjsua_media_config_default(&media_cfg) ï¼
åå§åå æ ä¸pjsua_init
å¯å¨ä¸å æ pjsua_start
ä»è¿éï¼ä½ æå 足çé ç½®é项 ï¼æ¥å¿ã åªä½ã 交éå·¥å ·çï¼
æ¨å¯ä»¥æ¾å°åºæ¬ PJSIP æç¨å¨è¿éï¼åéé¢ pjsip çæºçæ ¹è·¯å¾ï¼ä½ æä¸ä¸ªåºæ¬ ï¼ä½ä¸å¤å®æ´ï¼åºæ¬ç SIP 使ç¨æ åµï¼ å¨ï¼pjsip-apps/src/samples/simple_pjsua.c
ç¼è¾ï¼å¨çææ¶å¨ pjsip åºç¨ç¨åºç android 项ç®ï¼ä½ å¯ä»¥é¢ä¸´ä¸ä¸ªé®é¢ï¼å 为 pjsua app ä¸çæé»è®¤æ åµä¸ï¼å¯¹ä¸è¬çæ ï¼æ´å ·ä½å°è¯´ï¼pjsuaï¼ ç®æ ä¸å æ¬ææä¸ï¼ å¨ pjsip-åºç¨ç¨åº/çæ/çææ件çç®æ )ãè¥è¦ä¿®å¤è¿åªæ¯è½¬å° pjsip-åºç¨ç¨åº/å建åè¿è¡ï¼
使 pjsua
è¿å°å建å¨æ£ç¡®ç对象æ件: pjsip-apps/build/output/pjsua-arm-unknown-linux-androideabi/ (éè¦æ建 android æ ·æ¬æ¶)ã
ä¸æ¦ä½ ææç¸åºç对象æ件ï¼æ¨å¯ä»¥å¨ pjsip-åºç¨ç¨åº/src/pjsua/android ç³»ç»å次è¿è¡ ndk çæ
pjsip 本地视频预览怎么改变内容源的大小 iOS
1 把视频源当然文件来处理,sample有。不过这种方法用的不多。
2 修改vid_stream.c,在put_frame和get_frame里,置顶源码分析换上我们自己的视频源。这种方法使用的最多,很多人在1.x版本里支持视频,就用这种方法。
3 重新构造sdp,自己创建rtp通道。
在sdp上,pjsua_call_make_call这个函数非常方便,直接呼叫对方。不过它在底层做了太多工作,比如启动了声卡。而不用这个函数,直接用比较底层的pjsip_inv_send_msg,自己处理的工作相对比较多(但不难,不过这样就不需要pjsua这个现成的程序了,所以我们继续用pjsua_call_make_call)。
不过还好,pj库提供了大量的回调,其中一个:on_call_sdp_created,就是在创建sdp后回调上来,由我们自己再修改。比如我们自己定义rtp的端口g_local_port。
void on_call_sdp_created(pjsua_call_id call_id,
pjmedia_sdp_session *sdp,
pj_pool_t *pool,
const pjmedia_sdp_session *rem_sdp)
{
int nPort;
if (sdp != NULL)
{
pjmedia_sdp_media *m = sdp->media[sdp->media_count-1];
m->desc.port = g_local_port;
pjmedia_sdp_conn *c = sdp->conn;
char* addr;
if (c)
addr= c->addr.ptr;
else
{
const pj_str_t *hostname;
pj_sockaddr_in tmp_addr;
char *addr;
hostname = pj_gethostname();
pj_sockaddr_in_init(&tmp_addr, hostname, 0);
addr = pj_inet_ntoa(tmp_addr.sin_addr);
sdp->conn = (pjmedia_sdp_conn *)pj_pool_zalloc (pool, sizeof(pjmedia_sdp_conn));
sdp->conn->net_type = pj_str("IN");
sdp->conn->addr_type = pj_str("IP4");
sdp->conn->addr = pj_str(addr);
}
sdp->origin.addr = *pj_gethostname();
}
}
同样,这里还可以修改payload type等。
这是发起呼叫时的,接收方收到后的回应之后,也会触发这个回调,自己设定RTP端口,payload type就可以了。
2
呼叫成功后,双方建立起连接关系,这时需要传rtp数据了。pjsua把这些工作都放在底层了,不做任何修改,只需要在发送和接收时,自己做一些处理就行。
先说接收方(参考siprtp.c源码):
pj_status_t init_local_rtp()
{
if (m_bInitMedia)
{
destroy_media();
}
//g_local_port = local_port;
pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
pool = pj_pool_create(&(cp.factory), "test", , , NULL);
int status;
//status = pjmedia_endpt_create(&cp.factory, pjsip_endpt_get_ioqueue(pjsua_get_pjsip_endpt()), 0, &med_endpt);
status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
status = pjmedia_rtp_session_init(&video.out_sess, , pj_rand());
status = pjmedia_rtp_session_init(&video.in_sess, , 0);
status = pjmedia_transport_udp_create(med_endpt, NULL, g_local_port, 0, &video.transport);
m_bInitMedia = true;
video.active = true;
return 0;
}
这段代码是本地启动rtp一个端口用来接收视频数据。
然后,从sdp得到对方发送的ip和端口,调用pjmedia_transport_attach,建立关联就可以了。