⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g711.c

📁 基于sip协议的网络电话源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    pjmedia_codec *codec = NULL;    pj_status_t status;    PJ_ASSERT_RETURN(factory==&g711_factory.base, PJ_EINVAL);    /* Lock mutex. */    pj_mutex_lock(g711_factory.mutex);    /* Allocate new codec if no more is available */    if (pj_list_empty(&g711_factory.codec_list)) {	struct g711_private *codec_priv;	codec = pj_pool_alloc(g711_factory.pool, sizeof(pjmedia_codec));	codec_priv = pj_pool_zalloc(g711_factory.pool, 				    sizeof(struct g711_private));	if (!codec || !codec_priv) {	    pj_mutex_unlock(g711_factory.mutex);	    return PJ_ENOMEM;	}	/* Set the payload type */	codec_priv->pt = id->pt;	/* Create PLC, always with 10ms ptime */	status = pjmedia_plc_create(g711_factory.pool, 8000, 80,				    0, &codec_priv->plc);	if (status != PJ_SUCCESS) {	    pj_mutex_unlock(g711_factory.mutex);	    return status;	}	/* Create VAD */	status = pjmedia_silence_det_create(g711_factory.pool,					    8000, 80,					    &codec_priv->vad);	if (status != PJ_SUCCESS) {	    pj_mutex_unlock(g711_factory.mutex);	    return status;	}	codec->factory = factory;	codec->op = &g711_op;	codec->codec_data = codec_priv;    } else {	codec = g711_factory.codec_list.next;	pj_list_erase(codec);    }    /* Zero the list, for error detection in g711_dealloc_codec */    codec->next = codec->prev = NULL;    *p_codec = codec;    /* Unlock mutex. */    pj_mutex_unlock(g711_factory.mutex);    return PJ_SUCCESS;}static pj_status_t g711_dealloc_codec(pjmedia_codec_factory *factory, 				      pjmedia_codec *codec ){    struct g711_private *priv = codec->codec_data;    pj_int16_t frame[SAMPLES_PER_FRAME];    int i;    PJ_ASSERT_RETURN(factory==&g711_factory.base, PJ_EINVAL);    /* Check that this node has not been deallocated before */    pj_assert (codec->next==NULL && codec->prev==NULL);    if (codec->next!=NULL || codec->prev!=NULL) {	return PJ_EINVALIDOP;    }    /* Clear left samples in the PLC, since codec+plc will be reused     * next time.     */    for (i=0; i<2; ++i) {	pjmedia_zero_samples(frame, PJ_ARRAY_SIZE(frame));	pjmedia_plc_save(priv->plc, frame);    }    /* Lock mutex. */    pj_mutex_lock(g711_factory.mutex);    /* Insert at the back of the list */    pj_list_insert_before(&g711_factory.codec_list, codec);    /* Unlock mutex. */    pj_mutex_unlock(g711_factory.mutex);    return PJ_SUCCESS;}static pj_status_t g711_init( pjmedia_codec *codec, pj_pool_t *pool ){    /* There's nothing to do here really */    PJ_UNUSED_ARG(codec);    PJ_UNUSED_ARG(pool);    return PJ_SUCCESS;}static pj_status_t g711_open(pjmedia_codec *codec, 			     pjmedia_codec_param *attr ){    struct g711_private *priv = codec->codec_data;    priv->pt = attr->info.pt;    priv->plc_enabled = (attr->setting.plc != 0);    priv->vad_enabled = (attr->setting.vad != 0);    return PJ_SUCCESS;}static pj_status_t g711_close( pjmedia_codec *codec ){    PJ_UNUSED_ARG(codec);    /* Nothing to do */    return PJ_SUCCESS;}static pj_status_t  g711_modify(pjmedia_codec *codec, 			        const pjmedia_codec_param *attr ){    struct g711_private *priv = codec->codec_data;    if (attr->info.pt != priv->pt)	return PJMEDIA_EINVALIDPT;    priv->plc_enabled = (attr->setting.plc != 0);    priv->vad_enabled = (attr->setting.vad != 0);    return PJ_SUCCESS;}static pj_status_t  g711_parse( pjmedia_codec *codec,				void *pkt,				pj_size_t pkt_size,				const pj_timestamp *ts,				unsigned *frame_cnt,				pjmedia_frame frames[]){    unsigned count = 0;    PJ_UNUSED_ARG(codec);    PJ_ASSERT_RETURN(ts && frame_cnt && frames, PJ_EINVAL);    while (pkt_size >= FRAME_SIZE && count < *frame_cnt) {	frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;	frames[count].buf = pkt;	frames[count].size = FRAME_SIZE;	frames[count].timestamp.u64 = ts->u64 + SAMPLES_PER_FRAME * count;	pkt = ((char*)pkt) + FRAME_SIZE;	pkt_size -= FRAME_SIZE;	++count;    }    *frame_cnt = count;    return PJ_SUCCESS;}static pj_status_t  g711_encode(pjmedia_codec *codec, 				const struct pjmedia_frame *input,				unsigned output_buf_len, 				struct pjmedia_frame *output){    pj_int16_t *samples = (pj_int16_t*) input->buf;    struct g711_private *priv = codec->codec_data;    /* Check output buffer length */    if (output_buf_len < (input->size >> 1))	return PJMEDIA_CODEC_EFRMTOOSHORT;    /* Detect silence if VAD is enabled */    if (priv->vad_enabled) {	pj_bool_t is_silence;	pj_int32_t silence_period;	silence_period = pj_timestamp_diff32(&priv->last_tx,					     &input->timestamp);	is_silence = pjmedia_silence_det_detect(priv->vad, input->buf, 						(input->size >> 1), NULL);	if (is_silence && 	    PJMEDIA_CODEC_MAX_SILENCE_PERIOD != -1 &&	    silence_period < PJMEDIA_CODEC_MAX_SILENCE_PERIOD) 	{	    output->type = PJMEDIA_FRAME_TYPE_NONE;	    output->buf = NULL;	    output->size = 0;	    output->timestamp = input->timestamp;	    return PJ_SUCCESS;	} else {	    priv->last_tx = input->timestamp;	}    }    /* Encode */    if (priv->pt == PJMEDIA_RTP_PT_PCMA) {	unsigned i, n;	pj_uint8_t *dst = output->buf;	n = (input->size >> 1);	for (i=0; i!=n; ++i, ++dst) {	    *dst = pjmedia_linear2alaw(samples[i]);	}    } else if (priv->pt == PJMEDIA_RTP_PT_PCMU) {	unsigned i, n;	pj_uint8_t *dst = output->buf;	n = (input->size >> 1);	for (i=0; i!=n; ++i, ++dst) {	    *dst = pjmedia_linear2ulaw(samples[i]);	}    } else {	return PJMEDIA_EINVALIDPT;    }    output->type = PJMEDIA_FRAME_TYPE_AUDIO;    output->size = (input->size >> 1);    return PJ_SUCCESS;}static pj_status_t  g711_decode(pjmedia_codec *codec, 				const struct pjmedia_frame *input,				unsigned output_buf_len, 				struct pjmedia_frame *output){    struct g711_private *priv = codec->codec_data;    /* Check output buffer length */    PJ_ASSERT_RETURN(output_buf_len >= (input->size << 1),		     PJMEDIA_CODEC_EPCMTOOSHORT);    /* Input buffer MUST have exactly 80 bytes long */    PJ_ASSERT_RETURN(input->size == FRAME_SIZE, 		     PJMEDIA_CODEC_EFRMINLEN);    /* Decode */    if (priv->pt == PJMEDIA_RTP_PT_PCMA) {	unsigned i;	pj_uint8_t *src = input->buf;	pj_uint16_t *dst = output->buf;	for (i=0; i!=input->size; ++i) {	    *dst++ = (pj_uint16_t) pjmedia_alaw2linear(*src++);	}    } else if (priv->pt == PJMEDIA_RTP_PT_PCMU) {	unsigned i;	pj_uint8_t *src = input->buf;	pj_uint16_t *dst = output->buf;	for (i=0; i!=input->size; ++i) {	    *dst++ = (pj_uint16_t) pjmedia_ulaw2linear(*src++);	}    } else {	return PJMEDIA_EINVALIDPT;    }    output->type = PJMEDIA_FRAME_TYPE_AUDIO;    output->size = (input->size << 1);    if (priv->plc_enabled)	pjmedia_plc_save( priv->plc, output->buf);    return PJ_SUCCESS;}static pj_status_t  g711_recover( pjmedia_codec *codec,				  unsigned output_buf_len,				  struct pjmedia_frame *output){    struct g711_private *priv = codec->codec_data;    if (!priv->plc_enabled)	return PJ_EINVALIDOP;    PJ_ASSERT_RETURN(output_buf_len >= SAMPLES_PER_FRAME * 2, 		     PJMEDIA_CODEC_EPCMTOOSHORT);    pjmedia_plc_generate(priv->plc, output->buf);    output->size = SAMPLES_PER_FRAME * 2;    return PJ_SUCCESS;}#endif	/* PJMEDIA_HAS_G711_CODEC */

⌨️ 快捷键说明

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