Загрузка данных
/*
* Establish unidirectional media flow from souce to sink, with signal
* level adjustment.
*/
PJ_DEF(pj_status_t) pjsua_conf_connect2( pjsua_conf_port_id source,
pjsua_conf_port_id sink,
const pjsua_conf_connect_param *prm)
{
pj_status_t status = PJ_SUCCESS;
PJ_LOG(4,(THIS_FILE, "%s connect: %d --> %d",
(pjsua_var.is_mswitch ? "Switch" : "Conf"),
source, sink));
PJ_ASSERT_RETURN(source >= 0 && sink >= 0, PJ_EINVAL);
pj_log_push_indent();
PJSUA_LOCK();
/* If sound device idle timer is active, cancel it first. */
if (pjsua_var.snd_idle_timer.id) {
pjsip_endpt_cancel_timer(pjsua_var.endpt, &pjsua_var.snd_idle_timer);
pjsua_var.snd_idle_timer.id = PJ_FALSE;
}
/* For audio switchboard (i.e. APS-Direct):
* Check if sound device need to be reopened, i.e: its attributes
* (format, clock rate, channel count) must match to peer's.
* Note that sound device can be reopened only if it doesn't have
* any connection.
*/
if (pjsua_var.is_mswitch) {
pjmedia_conf_port_info port0_info;
pjmedia_conf_port_info peer_info;
unsigned peer_id;
pj_bool_t need_reopen = PJ_FALSE;
peer_id = (source!=0)? source : sink;
status = pjmedia_conf_get_port_info(pjsua_var.mconf, peer_id,
&peer_info);
pj_assert(status == PJ_SUCCESS);
status = pjmedia_conf_get_port_info(pjsua_var.mconf, 0, &port0_info);
pj_assert(status == PJ_SUCCESS);
/* Check if sound device is instantiated. */
need_reopen = (pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL &&
!pjsua_var.no_snd);
/* Check if sound device need to reopen because it needs to modify
* settings to match its peer. Sound device must be idle in this case
* though.
*/
if (!need_reopen &&
port0_info.listener_cnt==0 && port0_info.transmitter_cnt==0)
{
need_reopen = (peer_info.format.id != port0_info.format.id ||
peer_info.format.det.aud.avg_bps !=
port0_info.format.det.aud.avg_bps ||
peer_info.clock_rate != port0_info.clock_rate ||
peer_info.channel_count!=port0_info.channel_count);
}
if (need_reopen) {
if (pjsua_var.cap_dev != PJSUA_SND_NULL_DEV) {
pjmedia_snd_port_param param;
pjmedia_snd_port_param_default(¶m);
param.ec_options = pjsua_var.media_cfg.ec_options;
/* Create parameter based on peer info */
status = create_aud_param(¶m.base, pjsua_var.cap_dev,
pjsua_var.play_dev,
peer_info.clock_rate,
peer_info.channel_count,
peer_info.samples_per_frame,
peer_info.bits_per_sample,
PJ_FALSE);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error opening sound device",
status);
goto on_return;
}
/* And peer format */
if (peer_info.format.id != PJMEDIA_FORMAT_PCM) {
param.base.flags |= PJMEDIA_AUD_DEV_CAP_EXT_FORMAT;
param.base.ext_fmt = peer_info.format;
}
param.options = 0;
status = open_snd_dev(¶m);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error opening sound device",
status);
goto on_return;
}
} else {
/* Null-audio */
status = pjsua_set_snd_dev(pjsua_var.cap_dev,
pjsua_var.play_dev);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error opening sound device",
status);
goto on_return;
}
}
} else if (pjsua_var.no_snd) {
if (!pjsua_var.snd_is_on) {
pjsua_var.snd_is_on = PJ_TRUE;
/* Notify app */
if (pjsua_var.ua_cfg.cb.on_snd_dev_operation) {
(*pjsua_var.ua_cfg.cb.on_snd_dev_operation)(1);
}
}
}
} else {
/* The bridge version */
/* Create sound port if none is instantiated */
if (pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL &&
!pjsua_var.no_snd)
{
status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error opening sound device", status);
goto on_return;
}
} else if (pjsua_var.no_snd && !pjsua_var.snd_is_on) {
pjsua_var.snd_is_on = PJ_TRUE;
/* Notify app */
if (pjsua_var.ua_cfg.cb.on_snd_dev_operation) {
(*pjsua_var.ua_cfg.cb.on_snd_dev_operation)(1);
}
}
}
on_return:
PJSUA_UNLOCK();
if (status == PJ_SUCCESS) {
pjsua_conf_connect_param cc_param;
if (!prm)
pjsua_conf_connect_param_default(&cc_param);
else
pj_memcpy(&cc_param, prm, sizeof(cc_param));
status = pjmedia_conf_connect_port(pjsua_var.mconf, source, sink,
(int)((cc_param.level-1) * 128));
}
pj_log_pop_indent();
return status;
}
можно ли вызвать эту функцию в функции on_call_media_state(после согласования кодеков) только в том случае, если создан port0 и его параметры отличаются от peer(например clock_rate) - тогда выполнится код для need_reopen - переоткроется sound_device с нужными нам параметрами? Или в случае, если мы звоним удалённому абоненту, эту функцию нельзя вызывать?