freeswitchESL开发日志1
补振铃音和检测语音流
为了完善补振铃逻辑,需要对语音流进行检验,首先根据线程操作进行跟踪,发现freeswitch在不同的状态下用不同的函数进行收包操作。
在收包函数switch_core_session_read_frame中进行修改,在收包结束时进行检测收包内容如果为SFF_CNG(舒适噪音包)则判定收包失败,100次收包失败则认为无语音流,上报自定义事件(注意:协商为13或者设置通道静音会导致收到的所有包都是SFF_CNG)。
收到第一个正常包上报语音恢复事件。
参考链接
链接: link.
.
SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags,int stream_id)
{
........................
even_more_done:
if (!*frame ||
(!switch_test_flag(*frame, SFF_PROXY_PACKET) &&
(!(*frame)->codec || !(*frame)->codec->implementation || !switch_core_codec_ready((*frame)->codec)))) {
*frame = &runtime.dummy_cng_frame;
}
if(!*frame || switch_test_flag(*frame, SFF_CNG)){
if(switch_channel_get_callstate(session->channel) == CCS_EARLY && 0 == switch_channel_get_first_rtp_event(session->channel)){
if(switch_channel_get_no_rtp_count(session->channel) == 0){
switch_event_t* event;
if(switch_event_create_subclass(&event,SWITCH_EVENT_CUSTOM,"ccod::nortp") == SWITCH_STATUS_SUCCESS)
{
switch_channel_event_set_data(session->channel,event);
switch_event_fire(&event);
}
switch_channel_set_no_rtp_once(session->channel);
}else if(switch_channel_get_no_rtp_count(session->channel) > 0){
switch_channel_set_no_rtp_once(session->channel);
}
}
}else if(switch_channel_get_callstate(session->channel) == CCS_EARLY && 0 == switch_channel_get_first_rtp_event(session->channel)){
switch_event_t* event;
switch_channel_set_first_rtp_event(session->channel);
if(switch_event_create_subclass(&event,SWITCH_EVENT_CUSTOM,"ccod::firstrtp") == SWITCH_STATUS_SUCCESS)
{
switch_channel_event_set_data(session->channel,event);
switch_event_fire(&event);
}
}
switch_mutex_unlock(session->read_codec->mutex);
switch_mutex_unlock(session->codec_read_mutex);
if (status == SWITCH_STATUS_SUCCESS && switch_channel_get_callstate(session->channel) == CCS_UNHELD) {
switch_channel_set_callstate(session->channel, CCS_ACTIVE);
}
return status;
}