jbuf.c

来自「基于sip协议的网络电话源码」· C语言 代码 · 共 572 行 · 第 1/2 页

C
572
字号
    status = jb_framelist_init(pool, &jb->jb_framelist, frame_size, max_count);    if (status != PJ_SUCCESS)	return status;    pj_strdup_with_null(pool, &jb->name, name);    jb->jb_frame_size	 = frame_size;    jb->jb_frame_ptime   = ptime;    jb->jb_last_seq_no	 = -1;    jb->jb_level	 = 0;    jb->jb_last_level	 = 0;    jb->jb_last_jitter	 = 0;    jb->jb_last_op	 = JB_OP_INIT;    jb->jb_prefetch	 = PJ_MIN(PJMEDIA_JB_DEFAULT_INIT_DELAY,max_count*4/5);    jb->jb_prefetch_cnt	 = 0;    jb->jb_min_prefetch  = 0;    jb->jb_max_prefetch  = max_count*4/5;    jb->jb_stable_hist	 = 0;    jb->jb_status	 = JB_STATUS_INITIALIZING;    jb->jb_max_hist_jitter = 0;    jb->jb_max_count	 = max_count;    *p_jb = jb;    return PJ_SUCCESS;}/* * Set the jitter buffer to fixed delay mode. The default behavior * is to adapt the delay with actual packet delay. * */PJ_DEF(pj_status_t) pjmedia_jbuf_set_fixed( pjmedia_jbuf *jb,					    unsigned prefetch){    PJ_ASSERT_RETURN(jb, PJ_EINVAL);    PJ_ASSERT_RETURN(prefetch <= jb->jb_max_count, PJ_EINVAL);    jb->jb_min_prefetch = jb->jb_max_prefetch = 	jb->jb_prefetch = prefetch;    return PJ_SUCCESS;}/* * Set the jitter buffer to adaptive mode. */PJ_DEF(pj_status_t) pjmedia_jbuf_set_adaptive( pjmedia_jbuf *jb,					       unsigned prefetch,					       unsigned min_prefetch,					       unsigned max_prefetch){    PJ_ASSERT_RETURN(jb, PJ_EINVAL);    PJ_ASSERT_RETURN(min_prefetch < max_prefetch &&		     prefetch >= min_prefetch &&		     prefetch <= max_prefetch &&		     max_prefetch <= jb->jb_max_count,		     PJ_EINVAL);    jb->jb_prefetch = prefetch;    jb->jb_min_prefetch = min_prefetch;    jb->jb_max_prefetch = max_prefetch;    return PJ_SUCCESS;}PJ_DEF(pj_status_t) pjmedia_jbuf_reset(pjmedia_jbuf *jb){    jb->jb_last_seq_no	 = -1;    jb->jb_level	 = 0;    jb->jb_last_level	 = 0;    jb->jb_last_jitter	 = 0;    jb->jb_last_op	 = JB_OP_INIT;    jb->jb_prefetch_cnt	 = 0;    jb->jb_stable_hist	 = 0;    jb->jb_status	 = JB_STATUS_INITIALIZING;    jb->jb_max_hist_jitter = 0;    jb_framelist_remove_head(&jb->jb_framelist, 			     jb_framelist_size(&jb->jb_framelist));    return PJ_SUCCESS;}PJ_DEF(pj_status_t) pjmedia_jbuf_destroy(pjmedia_jbuf *jb){    return jb_framelist_destroy(&jb->jb_framelist);}static void jbuf_calculate_jitter(pjmedia_jbuf *jb){    unsigned stable_history_limit;    stable_history_limit = 1000 / jb->jb_frame_ptime;    jb->jb_last_jitter = PJ_ABS(jb->jb_level-jb->jb_last_level);    jb->jb_last_level = jb->jb_level;    jb->jb_max_hist_jitter = PJ_MAX(jb->jb_max_hist_jitter,jb->jb_last_jitter);    jb->jb_op_count++;    if (jb->jb_last_jitter < jb->jb_prefetch) {	jb->jb_stable_hist += jb->jb_last_jitter;	if (jb->jb_stable_hist > (int)stable_history_limit) {	    int seq_diff = (jb->jb_prefetch - jb->jb_max_hist_jitter)/3;	    if (seq_diff<1) seq_diff = 1;	    jb->jb_prefetch -= seq_diff;	    if (jb->jb_prefetch < jb->jb_min_prefetch) 		jb->jb_prefetch = jb->jb_min_prefetch;	    jb->jb_stable_hist = 0;	    jb->jb_max_hist_jitter = 0;	    TRACE__((THIS_FILE,"jb updated(1), prefetch=%d, size=%d", 		     jb->jb_prefetch, jb_framelist_size(&jb->jb_framelist)));	    /* These code is used to shorten the delay in the jitter buffer.	    if (jb->jb_op_count >= stable_history_limit*2 &&		(int)jb_framelist_size(&jb->jb_framelist) > jb->jb_prefetch+2)	    {		jb_framelist_remove_head(&jb->jb_framelist,1);		PJ_LOG(5,(jb->name.ptr, 			  "jbuf optimizing, prefetch: %d, size=%d", 			  jb->jb_prefetch,			  jb_framelist_size(&jb->jb_framelist)));		jb->jb_op_count = 0;	    }	    */	}    } else {	jb->jb_prefetch = PJ_MIN(jb->jb_last_jitter,				 (int)(jb->jb_max_count*4/5));	if (jb->jb_prefetch > jb->jb_max_prefetch)	    jb->jb_prefetch = jb->jb_max_prefetch;	jb->jb_stable_hist = 0;	jb->jb_max_hist_jitter = 0;	TRACE__((THIS_FILE,"jb updated(2), prefetch=%d, size=%d", 	         jb->jb_prefetch, jb_framelist_size(&jb->jb_framelist)));	/* These code is used to shorten the delay in the jitter buffer	   when the current size is larger than the prefetch. But it does	   not really work when the stream supports multiple frames, since	   the size may grow only temporarily.	if (jb->jb_op_count >= stable_history_limit * 2) {	    if ((int)jb_framelist_size(&jb->jb_framelist) > jb->jb_prefetch+2) 	    {		jb_framelist_remove_head(&jb->jb_framelist,1);		PJ_LOG(5,(jb->name.ptr, 			  "jbuf optimizing prefetch: %d, size=%d",			  jb->jb_prefetch,			  jb_framelist_size(&jb->jb_framelist)));	    }	    jb->jb_op_count = 0;	}	*/    }}static void jbuf_update(pjmedia_jbuf *jb, int oper){    if(jb->jb_last_op != oper) {	jbuf_calculate_jitter(jb);	jb->jb_last_op = oper;    }}PJ_DEF(void) pjmedia_jbuf_put_frame( pjmedia_jbuf *jb, 				     const void *frame, 				     pj_size_t frame_size, 				     int frame_seq){    pj_size_t min_frame_size;    int seq_diff;    if (jb->jb_last_seq_no == -1)	{	jb->jb_last_seq_no = frame_seq - 1;    }    seq_diff = frame_seq - jb->jb_last_seq_no;    jb->jb_last_seq_no = PJ_MAX(jb->jb_last_seq_no, frame_seq);    if (seq_diff > 0) jb->jb_level += seq_diff;    if(jb->jb_status ==	JB_STATUS_INITIALIZING) {	jb->jb_status = JB_STATUS_PROCESSING;	jb->jb_level = 0;	jb->jb_last_level = 0;	jb->jb_last_jitter = 0;    } else {	jbuf_update(jb, JB_OP_PUT);    }    min_frame_size = PJ_MIN(frame_size, jb->jb_frame_size);    if (seq_diff > 0) {	while (jb_framelist_put_at(&jb->jb_framelist,				   frame_seq,frame,min_frame_size) ==PJ_FALSE)	{	    jb_framelist_remove_head(&jb->jb_framelist,				     PJ_MAX(jb->jb_max_count/4,1) );	}	if (jb->jb_prefetch_cnt < jb->jb_prefetch)		    jb->jb_prefetch_cnt += seq_diff;    }    else    {	jb_framelist_put_at(&jb->jb_framelist,frame_seq,frame,min_frame_size);    }}/* * Get frame from jitter buffer. */PJ_DEF(void) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb, 				     void *frame, 				     char *p_frame_type){    pjmedia_jb_frame_type ftype;    jb->jb_level--;    jbuf_update(jb, JB_OP_GET);    if (jb_framelist_size(&jb->jb_framelist) == 0) {	jb->jb_prefetch_cnt = 0;    }    if ((jb->jb_prefetch_cnt < jb->jb_prefetch)) {	/* Can't return frame because jitter buffer is filling up	 * minimum prefetch.	 */	pj_bzero(frame, jb->jb_frame_size);	if (jb_framelist_size(&jb->jb_framelist) == 0)	    *p_frame_type = PJMEDIA_JB_ZERO_EMPTY_FRAME;	else	    *p_frame_type = PJMEDIA_JB_ZERO_PREFETCH_FRAME;	return;    }    /* Retrieve a frame from frame list */    if (jb_framelist_get(&jb->jb_framelist,frame,&ftype) == PJ_FALSE) {	/* Can't return frame because jitter buffer is empty! */	pj_bzero(frame, jb->jb_frame_size);	*p_frame_type = PJMEDIA_JB_ZERO_EMPTY_FRAME;	return;    }    /* We've successfully retrieved a frame from the frame list, but     * the frame could be a blank frame!     */    if (ftype == PJMEDIA_JB_NORMAL_FRAME) 	*p_frame_type	= PJMEDIA_JB_NORMAL_FRAME;    else 	*p_frame_type	= PJMEDIA_JB_MISSING_FRAME;}/* * Get jitter buffer state. */PJ_DEF(pj_status_t) pjmedia_jbuf_get_state( pjmedia_jbuf *jb,					    pjmedia_jb_state *state ){    PJ_ASSERT_RETURN(jb && state, PJ_EINVAL);    state->frame_size = jb->jb_frame_size;    state->prefetch = jb->jb_prefetch;    state->min_prefetch = jb->jb_min_prefetch;    state->max_prefetch = jb->jb_max_prefetch;    state->size = jb_framelist_size(&jb->jb_framelist);    return PJ_SUCCESS;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?