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

📄 pjsua_media.c

📁 基于sip协议的网络电话源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    return PJ_SUCCESS;}/* * Create UDP media transports for all the calls. This function creates * one UDP media transport for each call. */PJ_DEF(pj_status_t) pjsua_media_transports_create(const pjsua_transport_config *app_cfg){    pjsua_transport_config cfg;    unsigned i;    pj_status_t status;    /* Make sure pjsua_init() has been called */    PJ_ASSERT_RETURN(pjsua_var.ua_cfg.max_calls>0, PJ_EINVALIDOP);    PJSUA_LOCK();    /* Delete existing media transports */    for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {	if (pjsua_var.calls[i].med_tp != NULL) {	    pjsua_var.calls[i].med_tp->op->destroy(pjsua_var.calls[i].med_tp);	    pjsua_var.calls[i].med_tp = NULL;	}    }    /* Copy config */    pj_memcpy(&cfg, app_cfg, sizeof(*app_cfg));    pjsua_normalize_stun_config(&cfg.stun_config);    /* Create each media transport */    for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {	status = create_rtp_rtcp_sock(&cfg, &pjsua_var.calls[i].skinfo);	if (status != PJ_SUCCESS) {	    pjsua_perror(THIS_FILE, "Unable to create RTP/RTCP socket",		         status);	    goto on_error;	}	status = pjmedia_transport_udp_attach(pjsua_var.med_endpt, NULL,					      &pjsua_var.calls[i].skinfo, 0,					      &pjsua_var.calls[i].med_tp);	if (status != PJ_SUCCESS) {	    pjsua_perror(THIS_FILE, "Unable to create media transport",		         status);	    goto on_error;	}	pjmedia_transport_udp_simulate_lost(pjsua_var.calls[i].med_tp,					    PJMEDIA_DIR_ENCODING,					    pjsua_var.media_cfg.tx_drop_pct);	pjmedia_transport_udp_simulate_lost(pjsua_var.calls[i].med_tp,					    PJMEDIA_DIR_DECODING,					    pjsua_var.media_cfg.rx_drop_pct);    }    PJSUA_UNLOCK();    return PJ_SUCCESS;on_error:    for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {	if (pjsua_var.calls[i].med_tp != NULL) {	    pjsua_var.calls[i].med_tp->op->destroy(pjsua_var.calls[i].med_tp);	    pjsua_var.calls[i].med_tp = NULL;	}    }    PJSUA_UNLOCK();    return status;}/* * Get maxinum number of conference ports. */PJ_DEF(unsigned) pjsua_conf_get_max_ports(void){    return pjsua_var.media_cfg.max_media_ports;}/* * Get current number of active ports in the bridge. */PJ_DEF(unsigned) pjsua_conf_get_active_ports(void){    unsigned ports[256];    unsigned count = PJ_ARRAY_SIZE(ports);    pj_status_t status;    status = pjmedia_conf_enum_ports(pjsua_var.mconf, ports, &count);    if (status != PJ_SUCCESS)	count = 0;    return count;}/* * Enumerate all conference ports. */PJ_DEF(pj_status_t) pjsua_enum_conf_ports(pjsua_conf_port_id id[],					  unsigned *count){    return pjmedia_conf_enum_ports(pjsua_var.mconf, (unsigned*)id, count);}/* * Get information about the specified conference port */PJ_DEF(pj_status_t) pjsua_conf_get_port_info( pjsua_conf_port_id id,					      pjsua_conf_port_info *info){    pjmedia_conf_port_info cinfo;    unsigned i;    pj_status_t status;    status = pjmedia_conf_get_port_info( pjsua_var.mconf, id, &cinfo);    if (status != PJ_SUCCESS)	return status;    pj_bzero(info, sizeof(*info));    info->slot_id = id;    info->name = cinfo.name;    info->clock_rate = cinfo.clock_rate;    info->channel_count = cinfo.channel_count;    info->samples_per_frame = cinfo.samples_per_frame;    info->bits_per_sample = cinfo.bits_per_sample;    /* Build array of listeners */    info->listener_cnt = cinfo.listener_cnt;    for (i=0; i<cinfo.listener_cnt; ++i) {	info->listeners[i] = cinfo.listener_slots[i];    }    return PJ_SUCCESS;}/* * Add arbitrary media port to PJSUA's conference bridge. */PJ_DEF(pj_status_t) pjsua_conf_add_port( pj_pool_t *pool,					 pjmedia_port *port,					 pjsua_conf_port_id *p_id){    pj_status_t status;    status = pjmedia_conf_add_port(pjsua_var.mconf, pool,				   port, NULL, (unsigned*)p_id);    if (status != PJ_SUCCESS) {	if (p_id)	    *p_id = PJSUA_INVALID_ID;    }    return status;}/* * Remove arbitrary slot from the conference bridge. */PJ_DEF(pj_status_t) pjsua_conf_remove_port(pjsua_conf_port_id id){    return pjmedia_conf_remove_port(pjsua_var.mconf, (unsigned)id);}/* * Establish unidirectional media flow from souce to sink.  */PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,					pjsua_conf_port_id sink){    return pjmedia_conf_connect_port(pjsua_var.mconf, source, sink, 0);}/* * Disconnect media flow from the source to destination port. */PJ_DEF(pj_status_t) pjsua_conf_disconnect( pjsua_conf_port_id source,					   pjsua_conf_port_id sink){    return pjmedia_conf_disconnect_port(pjsua_var.mconf, source, sink);}/* * Adjust the signal level to be transmitted from the bridge to the  * specified port by making it louder or quieter. */PJ_DEF(pj_status_t) pjsua_conf_adjust_tx_level(pjsua_conf_port_id slot,					       float level){    return pjmedia_conf_adjust_tx_level(pjsua_var.mconf, slot,					(int)((level-1) * 128));}/* * Adjust the signal level to be received from the specified port (to * the bridge) by making it louder or quieter. */PJ_DEF(pj_status_t) pjsua_conf_adjust_rx_level(pjsua_conf_port_id slot,					       float level){    return pjmedia_conf_adjust_rx_level(pjsua_var.mconf, slot,					(int)((level-1) * 128));}/* * Get last signal level transmitted to or received from the specified port. */PJ_DEF(pj_status_t) pjsua_conf_get_signal_level(pjsua_conf_port_id slot,						unsigned *tx_level,						unsigned *rx_level){    return pjmedia_conf_get_signal_level(pjsua_var.mconf, slot, 					 tx_level, rx_level);}/***************************************************************************** * File player. *//* * Create a file player, and automatically connect this player to * the conference bridge. */PJ_DEF(pj_status_t) pjsua_player_create( const pj_str_t *filename,					 unsigned options,					 pjsua_player_id *p_id){    unsigned slot, file_id;    char path[PJ_MAXPATH];    pjmedia_port *port;    pj_status_t status;    if (pjsua_var.player_cnt >= PJ_ARRAY_SIZE(pjsua_var.player))	return PJ_ETOOMANY;    PJSUA_LOCK();    for (file_id=0; file_id<PJ_ARRAY_SIZE(pjsua_var.player); ++file_id) {	if (pjsua_var.player[file_id].port == NULL)	    break;    }    if (file_id == PJ_ARRAY_SIZE(pjsua_var.player)) {	/* This is unexpected */	PJSUA_UNLOCK();	pj_assert(0);	return PJ_EBUG;    }    pj_memcpy(path, filename->ptr, filename->slen);    path[filename->slen] = '\0';    status = pjmedia_wav_player_port_create(pjsua_var.pool, path,					    pjsua_var.mconf_cfg.samples_per_frame *					      1000 / pjsua_var.media_cfg.clock_rate, 					    options, 0, &port);    if (status != PJ_SUCCESS) {	PJSUA_UNLOCK();	pjsua_perror(THIS_FILE, "Unable to open file for playback", status);	return status;    }    status = pjmedia_conf_add_port(pjsua_var.mconf, pjsua_var.pool, 				   port, filename, &slot);    if (status != PJ_SUCCESS) {	pjmedia_port_destroy(port);	PJSUA_UNLOCK();	pjsua_perror(THIS_FILE, "Unable to add file to conference bridge", 		     status);	return status;    }    pjsua_var.player[file_id].type = 0;    pjsua_var.player[file_id].port = port;    pjsua_var.player[file_id].slot = slot;    if (p_id) *p_id = file_id;    ++pjsua_var.player_cnt;    PJSUA_UNLOCK();    return PJ_SUCCESS;}/* * Create a file playlist media port, and automatically add the port * to the conference bridge. */PJ_DEF(pj_status_t) pjsua_playlist_create( const pj_str_t file_names[],					   unsigned file_count,					   const pj_str_t *label,					   unsigned options,					   pjsua_player_id *p_id){    unsigned slot, file_id, ptime;    pjmedia_port *port;    pj_status_t status;    if (pjsua_var.player_cnt >= PJ_ARRAY_SIZE(pjsua_var.player))	return PJ_ETOOMANY;    PJSUA_LOCK();    for (file_id=0; file_id<PJ_ARRAY_SIZE(pjsua_var.player); ++file_id) {	if (pjsua_var.player[file_id].port == NULL)	    break;    }    if (file_id == PJ_ARRAY_SIZE(pjsua_var.player)) {	/* This is unexpected */	PJSUA_UNLOCK();	pj_assert(0);	return PJ_EBUG;    }    ptime = pjsua_var.mconf_cfg.samples_per_frame * 1000 / 	    pjsua_var.media_cfg.clock_rate;    status = pjmedia_wav_playlist_create(pjsua_var.pool, label, 					 file_names, file_count,					 ptime, options, 0, &port);    if (status != PJ_SUCCESS) {	PJSUA_UNLOCK();	pjsua_perror(THIS_FILE, "Unable to create playlist", status);	return status;    }    status = pjmedia_conf_add_port(pjsua_var.mconf, pjsua_var.pool, 				   port, &port->info.name, &slot);    if (status != PJ_SUCCESS) {	pjmedia_port_destroy(port);	PJSUA_UNLOCK();	pjsua_perror(THIS_FILE, "Unable to add port", status);	return status;    }    pjsua_var.player[file_id].type = 1;    pjsua_var.player[file_id].port = port;    pjsua_var.player[file_id].slot = slot;    if (p_id) *p_id = file_id;    ++pjsua_var.player_cnt;    PJSUA_UNLOCK();    return PJ_SUCCESS;}/* * Get conference port ID associated with player. */PJ_DEF(pjsua_conf_port_id) pjsua_player_get_conf_port(pjsua_player_id id){    PJ_ASSERT_RETURN(id>=0 && id<PJ_ARRAY_SIZE(pjsua_var.player), PJ_EINVAL);    PJ_ASSERT_RETURN(pjsua_var.player[id].port != NULL, PJ_EINVAL);    return pjsua_var.player[id].slot;}/* * Get the media port for the player. */PJ_DEF(pj_status_t) pjsua_player_get_port( pjsua_recorder_id id,					   pjmedia_port **p_port){    PJ_ASSERT_RETURN(id>=0 && id<PJ_ARRAY_SIZE(pjsua_var.player), PJ_EINVAL);    PJ_ASSERT_RETURN(pjsua_var.player[id].port != NULL, PJ_EINVAL);    PJ_ASSERT_RETURN(p_port != NULL, PJ_EINVAL);        *p_port = pjsua_var.player[id].port;    return PJ_SUCCESS;}/* * Set playback position. */PJ_DEF(pj_status_t) pjsua_player_set_pos( pjsua_player_id id,					  pj_uint32_t samples){    PJ_ASSERT_RETURN(id>=0 && id<PJ_ARRAY_SIZE(pjsua_var.player), PJ_EINVAL);    PJ_ASSERT_RETURN(pjsua_var.player[id].port != NULL, PJ_EINVAL);    PJ_ASSERT_RETURN(pjsua_var.player[id].type == 0, PJ_EINVAL);    return pjmedia_wav_player_port_set_pos(pjsua_var.player[id].port, samples);}/* * Close the file, remove the player from the bridge, and free * resources associated with the file player. */PJ_DEF(pj_status_t) pjsua_player_destroy(pjsua_player_id id){    PJ_ASSERT_RETURN(id>=0 && id<PJ_ARRAY_SIZE(pjsua_var.player), PJ_EINVAL);    PJ_ASSERT_RETURN(pjsua_var.player[id].port != NULL, PJ_EINVAL);    PJSUA_LOCK();    if (pjsua_var.player[id].port) {	pjmedia_conf_remove_port(pjsua_var.mconf, 				 pjsua_var.player[id].slot);	pjmedia_port_destroy(pjsua_var.player[id].port);	pjsua_var.player[id].port = NULL;	pjsua_var.player[id].slot = 0xFFFF;	pjsua_var.player_cnt--;    }    PJSUA_UNLOCK();    return PJ_SUCCESS;}/***************************************************************************** * File recorder. *//* * Create a file recorder, and automatically connect this recorder to * the conference bridge. */PJ_DEF(pj_status_t) pjsua_recorder_create( const pj_str_t *filename,					   unsigned enc_type,					   void *enc_param,					   pj_ssize_t max_size,					   unsigned options,					   pjsua_recorder_id *p_id){    enum Format    {	FMT_UNKNOWN,	FMT_WAV,	FMT_MP3,    };    unsigned slot, file_id;    char path[PJ_MAXPATH];    pj_str_t ext;    int file_format;    pjmedia_port *port;    pj_status_t status;    /* Filename must present */    PJ_ASSERT_RETURN(filename != NULL, PJ_EINVAL);    /* Don't support max_size at present */    PJ_ASSERT_RETURN(max_size == 0 || max_size == -1, PJ_EINVAL);    /* Don't support encoding type at present */    PJ_ASSERT_RETURN(enc_type == 0, PJ_EINVAL);    if (pjsua_var.rec_cnt >= PJ_ARRAY_SIZE(pjsua_var.recorder))	return PJ_ETOOMANY;    /* Determine the file format */

⌨️ 快捷键说明

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