GB28181---基於pjsip庫的開發(一)

   《GBT 28181-2016 公共安全視頻監控聯網系統信息傳輸、交換、控制技術要求》規定了公共安全視頻監控聯網系統的互聯結構、傳輸、交換、控制的基本要求和安全性要求、以及控制傳輸流程和協議接口等技術要求。

在音視頻領域內,如果你們產品定位不是消費級別的,而是需要做走平臺,做對接。那gb28181協議是避不開的。

而該協議對外有2011和2016兩版,其後主要更新了TCP傳輸、強制I幀等內容。具體的內容我就不介紹了,網上一搜一大把。我們主要說說對該協議的開發吧。

由於gb28181是基於sip協議進行傳輸的一項協議,那我們就有目標了,先找個開源sip庫,不管你選的是osip、exosip、還是pjsip都沒關係,他們都只是載體,大佬們都說pjsip代碼優雅,那我們就選pjsip吧,接下來我們就具體講講pjsip庫的一些東西吧(不會有人選opensip吧)。

PJSIP is a free and open source multimedia communication library written in C language implementing standard based protocols such as SIP, SDP, RTP, STUN, TURN, and ICE. It combines signaling protocol (SIP) with rich multimedia framework and NAT traversal functionality into high level API that is portable and suitable for almost any type of systems ranging from desktops, embedded systems, to mobile handsets.

介紹你們想了解的就去他們官網 https://www.pjsip.org/ 吧。

裏面有開發指南,說的很全面。

將開源庫編譯完之後我們會用到他們的三個庫,分別爲pjlib、pjlib-util、以及pjsip。將他們的頭文件及庫加入到我們的項目中,我們就能使用了。

現在我們來將pj庫進行初始化。好的,上代碼。獻醜了

typedef struct 
{

	pjsip_endpoint  *pj_endpt;
	pjsip_transport *pj_port;
	pj_caching_pool pj_cach_pool;
	pj_thread_t *thread_id;
	
}PJSIP_PARAM_S,*PPJSIP_PARAM_S;
#define PJSIP_PARAM_S_LEN sizeof(PJSIP_PARAM_S)

static PJSIP_PARAM_S gb_pjsip;

static pj_bool_t pjsip_msg_request(pjsip_rx_data *rdata);
static pjsip_method  pjsip_message_method = {PJSIP_OTHER_METHOD, { "MESSAGE", 7 }};

static pjsip_module mod_msg = 
{
    NULL, NULL,						/* prev, next.		*/
    { "mod_msg", 7 },				/* Name.		*/
    -1,								/* Id			*/
    PJSIP_MOD_PRIORITY_APPLICATION,	/* Priority	       */
    NULL,							/* load()			*/
    NULL,							/* start()		*/
    NULL,							/* stop()		*/
    NULL,							/* unload()		*/
    &pjsip_msg_request,				/* on_rx_request()	*/
    NULL,							/* on_rx_response()	*/
    NULL,							/* on_tx_request.		*/
    NULL,							/* on_tx_response()	*/
    NULL,							/* on_tsx_state()		*/
};


/*初始化pj庫;分配內存,開啓鏈路*/
int init_pjlib(void)
{
	pj_status_t 	status; 
	pj_sockaddr_in	addr;
	pjsip_ua_init_param  ua_init_param;
	pj_pool_t	   *pool;
	
	memset(&gb_pjsip, 0, PJSIP_PARAM_S_LEN);

	//屏蔽系統日誌
	pj_log_set_level(0);
	pj_log_set_decor(PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME | PJ_LOG_HAS_MICRO_SEC);

	if (pj_init() != PJ_SUCCESS)
	{
		return -1;
	}
	
	/*	init pjlib_util  */
	if (pjlib_util_init() != PJ_SUCCESS)
	{
		return -1;
	}

	pj_caching_pool_init(&gb_pjsip.pj_cach_pool, &pj_pool_factory_default_policy, (2<<20));

	/*	create endpoint  */
	status = pjsip_endpt_create(&gb_pjsip.pj_cach_pool.factory, "endpt", &gb_pjsip.pj_endpt);
	if (status != PJ_SUCCESS)
	{
		pj_caching_pool_destroy(&gb_pjsip.pj_cach_pool);
		return -1;
	}
	
	/* Start transaction layer module. */
	status = pjsip_tsx_layer_init_module(gb_pjsip.pj_endpt);
	if (status != PJ_SUCCESS)
	{
		pjsip_endpt_destroy(gb_pjsip.pj_endpt);
		pj_caching_pool_destroy(&gb_pjsip.pj_cach_pool);
		return -1;
	}
	
	/* Start UDP transport. */
	pj_sockaddr_in_init(&addr, NULL, (pj_uint16_t)5060);
	status = pjsip_udp_transport_start(gb_pjsip.pj_endpt,&addr, NULL, 1, &gb_pjsip.pj_port);
	if (status != PJ_SUCCESS) 
	{
		pjsip_endpt_destroy(gb_pjsip.pj_endpt);
		pj_caching_pool_destroy(&gb_pjsip.pj_cach_pool);
		return -1;
	}
	
	pj_bzero(&ua_init_param, sizeof(ua_init_param));
	status = pjsip_ua_init_module(gb_pjsip.pj_endpt, &ua_init_param);
	if (status != PJ_SUCCESS) 
	{
		pjsip_transport_destroy(gb_pjsip.pj_port);
		pjsip_endpt_destroy(gb_pjsip.pj_endpt);
		pj_caching_pool_destroy(&gb_pjsip.pj_cach_pool);
		return -1;
	}
	
	/*註冊pjsip消息模塊*/
	status = pjsip_endpt_register_module(gb_pjsip.pj_endpt, &mod_msg);
	if (status != PJ_SUCCESS)
	{
		return -1;
	}
	
	pool = pjsip_endpt_create_pool(gb_pjsip.pj_endpt, "thread%p", 2048, 2048);
	status = pj_thread_create(pool, "pjsip_task", &pjsip_thread_task, NULL, 0, 0, &gb_pjsip.thread_id);//create thread
	if (status != PJ_SUCCESS)
	{
		pjsip_transport_destroy(gb_pjsip.pj_port);
		pjsip_endpt_destroy(gb_pjsip.pj_endpt);
		pj_caching_pool_destroy(&gb_pjsip.pj_cach_pool);
		return -1;
	}
	printf("init_pjlib finish\n");
	
	return 0;
}

初始化完成之後,sip消息都會通過pj庫處理進入回調函數pj_bool_t pjsip_msg_request(pjsip_rx_data *rdata);來處理我們的邏輯業務了。

雖然我們完成了pjsip的初始化,但是想要靈活運用還得多研究研究,之後我們花幾篇文章來了解了解這個pj庫吧。

有錯誤請留言,謝謝

下篇繼續

GB28181---基於pjsip庫的開發(二)

---------------bob 2020/5/6

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章