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

📄 pjsua_media.c

📁 基于sip协议的网络电话源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    ext.ptr = filename->ptr + filename->slen - 4;    ext.slen = 4;    if (pj_stricmp2(&ext, ".wav") == 0)	file_format = FMT_WAV;    else if (pj_stricmp2(&ext, ".mp3") == 0)	file_format = FMT_MP3;    else {	PJ_LOG(1,(THIS_FILE, "pjsua_recorder_create() error: unable to "			     "determine file format for %.*s",			     (int)filename->slen, filename->ptr));	return PJ_ENOTSUP;    }    PJSUA_LOCK();    for (file_id=0; file_id<PJ_ARRAY_SIZE(pjsua_var.recorder); ++file_id) {	if (pjsua_var.recorder[file_id].port == NULL)	    break;    }    if (file_id == PJ_ARRAY_SIZE(pjsua_var.recorder)) {	/* This is unexpected */	PJSUA_UNLOCK();	pj_assert(0);	return PJ_EBUG;    }    pj_memcpy(path, filename->ptr, filename->slen);    path[filename->slen] = '\0';    if (file_format == FMT_WAV) {	status = pjmedia_wav_writer_port_create(pjsua_var.pool, path, 						pjsua_var.media_cfg.clock_rate, 						pjsua_var.mconf_cfg.channel_count,						pjsua_var.mconf_cfg.samples_per_frame,						pjsua_var.mconf_cfg.bits_per_sample, 						options, 0, &port);    } else if (file_format == FMT_MP3) {	status = pjmedia_mp3_writer_port_create(pjsua_var.pool, path,						pjsua_var.media_cfg.clock_rate,						pjsua_var.mconf_cfg.channel_count,						pjsua_var.mconf_cfg.samples_per_frame,						pjsua_var.mconf_cfg.bits_per_sample,						enc_param, &port);    } else {	port = NULL;	status = PJ_ENOTSUP;    }    if (status != PJ_SUCCESS) {	PJSUA_UNLOCK();	pjsua_perror(THIS_FILE, "Unable to open file for recording", 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();	return status;    }    pjsua_var.recorder[file_id].port = port;    pjsua_var.recorder[file_id].slot = slot;    if (p_id) *p_id = file_id;    ++pjsua_var.rec_cnt;    PJSUA_UNLOCK();    return PJ_SUCCESS;}/* * Get conference port associated with recorder. */PJ_DEF(pjsua_conf_port_id) pjsua_recorder_get_conf_port(pjsua_recorder_id id){    PJ_ASSERT_RETURN(id>=0 && id<PJ_ARRAY_SIZE(pjsua_var.recorder), PJ_EINVAL);    PJ_ASSERT_RETURN(pjsua_var.recorder[id].port != NULL, PJ_EINVAL);    return pjsua_var.recorder[id].slot;}/* * Get the media port for the recorder. */PJ_DEF(pj_status_t) pjsua_recorder_get_port( pjsua_recorder_id id,					     pjmedia_port **p_port){    PJ_ASSERT_RETURN(id>=0 && id<PJ_ARRAY_SIZE(pjsua_var.recorder), PJ_EINVAL);    PJ_ASSERT_RETURN(pjsua_var.recorder[id].port != NULL, PJ_EINVAL);    PJ_ASSERT_RETURN(p_port != NULL, PJ_EINVAL);    *p_port = pjsua_var.recorder[id].port;    return PJ_SUCCESS;}/* * Destroy recorder (this will complete recording). */PJ_DEF(pj_status_t) pjsua_recorder_destroy(pjsua_recorder_id id){    PJ_ASSERT_RETURN(id>=0 && id<PJ_ARRAY_SIZE(pjsua_var.recorder), PJ_EINVAL);    PJ_ASSERT_RETURN(pjsua_var.recorder[id].port != NULL, PJ_EINVAL);    PJSUA_LOCK();    if (pjsua_var.recorder[id].port) {	pjmedia_conf_remove_port(pjsua_var.mconf, 				 pjsua_var.recorder[id].slot);	pjmedia_port_destroy(pjsua_var.recorder[id].port);	pjsua_var.recorder[id].port = NULL;	pjsua_var.recorder[id].slot = 0xFFFF;	pjsua_var.rec_cnt--;    }    PJSUA_UNLOCK();    return PJ_SUCCESS;}/***************************************************************************** * Sound devices. *//* * Enum sound devices. */PJ_DEF(pj_status_t) pjsua_enum_snd_devs( pjmedia_snd_dev_info info[],					 unsigned *count){    unsigned i, dev_count;    dev_count = pjmedia_snd_get_dev_count();        if (dev_count > *count) dev_count = *count;    for (i=0; i<dev_count; ++i) {	const pjmedia_snd_dev_info *ci;	ci = pjmedia_snd_get_dev_info(i);	pj_memcpy(&info[i], ci, sizeof(*ci));    }    *count = dev_count;    return PJ_SUCCESS;}/* Close existing sound device */static void close_snd_dev(void){    /* Close sound device */    if (pjsua_var.snd_port) {	const pjmedia_snd_dev_info *cap_info, *play_info;	cap_info = pjmedia_snd_get_dev_info(pjsua_var.cap_dev);	play_info = pjmedia_snd_get_dev_info(pjsua_var.play_dev);	PJ_LOG(4,(THIS_FILE, "Closing %s sound playback device and "			     "%s sound capture device",			     play_info->name, cap_info->name));	pjmedia_snd_port_disconnect(pjsua_var.snd_port);	pjmedia_snd_port_destroy(pjsua_var.snd_port);	pjsua_var.snd_port = NULL;    }    /* Close null sound device */    if (pjsua_var.null_snd) {	PJ_LOG(4,(THIS_FILE, "Closing null sound device.."));	pjmedia_master_port_destroy(pjsua_var.null_snd, PJ_FALSE);	pjsua_var.null_snd = NULL;    }}/* * Select or change sound device. Application may call this function at * any time to replace current sound device. */PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,				       int playback_dev){    pjmedia_port *conf_port;    const pjmedia_snd_dev_info *play_info;    unsigned clock_rates[] = { 0, 22050, 44100, 48000, 11025, 32000, 8000};    unsigned selected_clock_rate = 0;    unsigned i;    pjmedia_snd_stream *strm;    pjmedia_snd_stream_info si;    pj_str_t tmp;    pj_status_t status = -1;    /* Close existing sound port */    close_snd_dev();    /* Set default clock rate */    clock_rates[0] = pjsua_var.media_cfg.clock_rate;    /* Attempts to open the sound device with different clock rates */    for (i=0; i<PJ_ARRAY_SIZE(clock_rates); ++i) {	char errmsg[PJ_ERR_MSG_SIZE];	PJ_LOG(4,(THIS_FILE, 		  "pjsua_set_snd_dev(): attempting to open devices "		  "@%d Hz", clock_rates[i]));	/* Create the sound device. Sound port will start immediately. */	status = pjmedia_snd_port_create(pjsua_var.pool, capture_dev,					 playback_dev, 					 clock_rates[i], 1,					 clock_rates[i]/FPS,					 16, 0, &pjsua_var.snd_port);	if (status == PJ_SUCCESS) {	    selected_clock_rate = clock_rates[i];	    break;	}	pj_strerror(status, errmsg, sizeof(errmsg));	PJ_LOG(4, (THIS_FILE, "..failed: %s", errmsg));    }    if (status != PJ_SUCCESS) {	pjsua_perror(THIS_FILE, "Unable to open sound device", status);	return status;    }    /* Get the port0 of the conference bridge. */    conf_port = pjmedia_conf_get_master_port(pjsua_var.mconf);    pj_assert(conf_port != NULL);    /* Set AEC */    pjmedia_snd_port_set_ec( pjsua_var.snd_port, pjsua_var.pool, 			     pjsua_var.media_cfg.ec_tail_len, 			     pjsua_var.media_cfg.ec_options);    /* If there's mismatch between sound port and conference's port,     * create a resample port to bridge them.     */    if (selected_clock_rate != pjsua_var.media_cfg.clock_rate) {	pjmedia_port *resample_port;	status = pjmedia_resample_port_create(pjsua_var.pool, conf_port, 					      selected_clock_rate, 0, 					      &resample_port);	if (status != PJ_SUCCESS) {	    pjsua_perror("Error creating resample port", THIS_FILE, status);	    return status;	}	conf_port = resample_port;    }    /* Connect sound port to the bridge */ 	     status = pjmedia_snd_port_connect(pjsua_var.snd_port, 	 				      conf_port ); 	     if (status != PJ_SUCCESS) { 	 	pjsua_perror(THIS_FILE, "Unable to connect conference port to "			        "sound device", status); 	 	pjmedia_snd_port_destroy(pjsua_var.snd_port); 	 	pjsua_var.snd_port = NULL; 	 	return status; 	     }    /* Save the device IDs */    pjsua_var.cap_dev = capture_dev;    pjsua_var.play_dev = playback_dev;    /* Update sound device name. */    strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port);    pjmedia_snd_stream_get_info(strm, &si);    play_info = pjmedia_snd_get_dev_info(si.rec_id);    pjmedia_conf_set_port0_name(pjsua_var.mconf, 				pj_cstr(&tmp, play_info->name));    return PJ_SUCCESS;}/* * Get currently active sound devices. If sound devices has not been created * (for example when pjsua_start() is not called), it is possible that * the function returns PJ_SUCCESS with -1 as device IDs. */PJ_DEF(pj_status_t) pjsua_get_snd_dev(int *capture_dev,				      int *playback_dev){    if (capture_dev) {	*capture_dev = pjsua_var.cap_dev;    }    if (playback_dev) {	*playback_dev = pjsua_var.play_dev;    }    return PJ_SUCCESS;}/* * Use null sound device. */PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void){    pjmedia_port *conf_port;    pj_status_t status;    /* Close existing sound device */    close_snd_dev();    PJ_LOG(4,(THIS_FILE, "Opening null sound device.."));    /* Get the port0 of the conference bridge. */    conf_port = pjmedia_conf_get_master_port(pjsua_var.mconf);    pj_assert(conf_port != NULL);    /* Create master port, connecting port0 of the conference bridge to     * a null port.     */    status = pjmedia_master_port_create(pjsua_var.pool, pjsua_var.null_port,					conf_port, 0, &pjsua_var.null_snd);    if (status != PJ_SUCCESS) {	pjsua_perror(THIS_FILE, "Unable to create null sound device",		     status);	return status;    }    /* Start the master port */    status = pjmedia_master_port_start(pjsua_var.null_snd);    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);    return PJ_SUCCESS;}/* * Use no device! */PJ_DEF(pjmedia_port*) pjsua_set_no_snd_dev(void){    /* Close existing sound device */    close_snd_dev();    pjsua_var.no_snd = PJ_TRUE;    return pjmedia_conf_get_master_port(pjsua_var.mconf);}/* * Configure the AEC settings of the sound port. */PJ_DEF(pj_status_t) pjsua_set_ec(unsigned tail_ms, unsigned options){    pjsua_var.media_cfg.ec_tail_len = tail_ms;    if (pjsua_var.snd_port)	return pjmedia_snd_port_set_ec( pjsua_var.snd_port, pjsua_var.pool,					tail_ms, options);        return PJ_SUCCESS;}/* * Get current AEC tail length. */PJ_DEF(pj_status_t) pjsua_get_ec_tail(unsigned *p_tail_ms){    *p_tail_ms = pjsua_var.media_cfg.ec_tail_len;    return PJ_SUCCESS;}/***************************************************************************** * Codecs. *//* * Enum all supported codecs in the system. */PJ_DEF(pj_status_t) pjsua_enum_codecs( pjsua_codec_info id[],				       unsigned *p_count ){    pjmedia_codec_mgr *codec_mgr;    pjmedia_codec_info info[32];    unsigned i, count, prio[32];    pj_status_t status;    codec_mgr = pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt);    count = PJ_ARRAY_SIZE(info);    status = pjmedia_codec_mgr_enum_codecs( codec_mgr, &count, info, prio);    if (status != PJ_SUCCESS) {	*p_count = 0;	return status;    }    if (count > *p_count) count = *p_count;    for (i=0; i<count; ++i) {	pjmedia_codec_info_to_id(&info[i], id[i].buf_, sizeof(id[i].buf_));	id[i].codec_id = pj_str(id[i].buf_);	id[i].priority = (pj_uint8_t) prio[i];    }    *p_count = count;    return PJ_SUCCESS;}/* * Change codec priority. */PJ_DEF(pj_status_t) pjsua_codec_set_priority( const pj_str_t *codec_id,					      pj_uint8_t priority ){    pjmedia_codec_mgr *codec_mgr;    codec_mgr = pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt);    return pjmedia_codec_mgr_set_codec_priority(codec_mgr, codec_id, 					        priority);}/* * Get codec parameters. */PJ_DEF(pj_status_t) pjsua_codec_get_param( const pj_str_t *codec_id,					   pjmedia_codec_param *param ){    const pjmedia_codec_info *info;    pjmedia_codec_mgr *codec_mgr;    unsigned count = 1;    pj_status_t status;    codec_mgr = pjmedia_endpt_get_codec_mgr(pjsua_var.med_endpt);    status = pjmedia_codec_mgr_find_codecs_by_id(codec_mgr, codec_id,						 &count, &info, NULL);    if (status != PJ_SUCCESS)	return status;    if (count != 1)	return PJ_ENOTFOUND;    status = pjmedia_codec_mgr_get_default_param( codec_mgr, info, param);    return status;}/* * Set codec parameters. */PJ_DEF(pj_status_t) pjsua_codec_set_param( const pj_str_t *id,					   const pjmedia_codec_param *param){    PJ_UNUSED_ARG(id);    PJ_UNUSED_ARG(param);    PJ_TODO(set_codec_param);    return PJ_SUCCESS;}

⌨️ 快捷键说明

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