rework media code

This commit is contained in:
Anthony Minessale 2013-11-08 03:48:00 +05:00
parent 73c4eb5f10
commit bb9adff511
14 changed files with 1166 additions and 804 deletions

View File

@ -178,6 +178,7 @@ struct switch_core_session {
switch_size_t recur_buffer_len;
switch_media_handle_t *media_handle;
uint32_t decoder_errors;
};
struct switch_media_bug {

View File

@ -68,7 +68,6 @@ typedef enum {
SCMF_RUNNING,
SCMF_DISABLE_TRANSCODING,
SCMF_AUTOFIX_TIMING,
SCMF_AUTOFIX_PT,
SCMF_CODEC_GREEDY,
SCMF_CODEC_SCROOGE,
SCMF_DISABLE_HOLD,
@ -81,6 +80,8 @@ typedef enum {
SCMF_AUTOFLUSH,
SCMF_REWRITE_TIMESTAMPS,
SCMF_RTP_AUTOFLUSH_DURING_BRIDGE,
SCMF_MULTI_ANSWER_AUDIO,
SCMF_MULTI_ANSWER_VIDEO,
SCMF_MAX
} switch_core_media_flag_t;
@ -156,6 +157,53 @@ typedef struct switch_core_media_params_s {
} switch_core_media_params_t;
typedef struct xpayload_map_s {
uint32_t pt;
uint32_t send_pt;
uint32_t rate;
uint32_t ptime;
switch_media_type_t type;
uint8_t negotiated;
char *name;
switch_sdp_type_t sdp_type;
unsigned long hash;
struct xpayload_map_s *next;
} xpayload_map_t;
typedef struct payload_map_s {
switch_media_type_t type;
switch_sdp_type_t sdp_type;
uint32_t ptime;
uint32_t rate;
uint8_t allocated;
uint8_t negotiated;
unsigned long hash;
char *rm_encoding;
char *iananame;
switch_payload_t pt;
unsigned long rm_rate;
unsigned long adv_rm_rate;
uint32_t codec_ms;
uint32_t bitrate;
char *rm_fmtp;
switch_payload_t agreed_pt;
switch_payload_t recv_pt;
char *fmtp_out;
char *remote_sdp_ip;
switch_port_t remote_sdp_port;
int channels;
int adv_channels;
struct payload_map_s *next;
} payload_map_t;
static inline const char *switch_media_type2str(switch_media_type_t type)
{
switch(type) {
@ -216,7 +264,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
SWITCH_DECLARE(switch_status_t) switch_core_media_ext_address_lookup(switch_core_session_t *session, char **ip, switch_port_t *port, const char *sourceip);
SWITCH_DECLARE(switch_status_t) switch_core_media_process_t38_passthru(switch_core_session_t *session,
switch_core_session_t *other_session, switch_t38_options_t *t38_options);
SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *session, const char *ip, switch_port_t port, const char *sr, int force);
SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *session, switch_sdp_type_t sdp_type,
const char *ip, switch_port_t port, const char *sr, int force);
SWITCH_DECLARE(void)switch_core_media_set_local_sdp(switch_core_session_t *session, const char *sdp_str, switch_bool_t dup);
SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session);
SWITCH_DECLARE(void) switch_core_media_set_udptl_image_sdp(switch_core_session_t *session, switch_t38_options_t *t38_options, int insist);
@ -232,7 +281,6 @@ SWITCH_DECLARE(void) switch_core_media_kill_socket(switch_core_session_t *sessio
SWITCH_DECLARE(switch_status_t) switch_core_media_queue_rfc2833(switch_core_session_t *session, switch_media_type_t type, const switch_dtmf_t *dtmf);
SWITCH_DECLARE(switch_status_t) switch_core_media_queue_rfc2833_in(switch_core_session_t *session, switch_media_type_t type, const switch_dtmf_t *dtmf);
SWITCH_DECLARE(uint8_t) switch_core_media_ready(switch_core_session_t *session, switch_media_type_t type);
SWITCH_DECLARE(void) switch_core_media_set_recv_pt(switch_core_session_t *session, switch_media_type_t type, switch_payload_t pt);
SWITCH_DECLARE(void) switch_core_media_set_telephony_event(switch_core_session_t *session, switch_media_type_t type, switch_payload_t te);
SWITCH_DECLARE(void) switch_core_media_set_telephony_recv_event(switch_core_session_t *session, switch_media_type_t type, switch_payload_t te);
SWITCH_DECLARE(switch_rtp_stats_t *) switch_core_media_stats(switch_core_session_t *session, switch_media_type_t type, switch_memory_pool_t *pool);
@ -257,6 +305,14 @@ SWITCH_DECLARE(void) switch_core_media_deinit(void);
SWITCH_DECLARE(void) switch_core_media_set_stats(switch_core_session_t *session);
SWITCH_DECLARE(void) switch_core_session_wake_video_thread(switch_core_session_t *session);
SWITCH_DECLARE(void) switch_core_session_clear_crypto(switch_core_session_t *session);
SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_session_t *session,
switch_media_type_t type,
const char *name,
switch_sdp_type_t sdp_type,
uint32_t pt,
uint32_t rate,
uint32_t ptime,
uint8_t negotiated);
SWITCH_END_EXTERN_C
#endif

View File

@ -37,6 +37,7 @@
#define SWITCH_FRAME_H
#include <switch.h>
#include <switch_core_media.h>
SWITCH_BEGIN_EXTERN_C
/*! \brief An abstraction of a data frame */
@ -71,6 +72,7 @@ SWITCH_BEGIN_EXTERN_C
/*! frame flags */
switch_frame_flag_t flags;
void *user_data;
payload_map_t *pmap;
};
SWITCH_END_EXTERN_C

View File

@ -485,7 +485,6 @@ SWITCH_DECLARE(void) switch_rtp_set_private(switch_rtp_t *rtp_session, void *pri
*/
SWITCH_DECLARE(void) switch_rtp_set_telephony_event(switch_rtp_t *rtp_session, switch_payload_t te);
SWITCH_DECLARE(void) switch_rtp_set_telephony_recv_event(switch_rtp_t *rtp_session, switch_payload_t te);
SWITCH_DECLARE(void) switch_rtp_set_recv_pt(switch_rtp_t *rtp_session, switch_payload_t pt);
/*!
\brief Set the payload type for comfort noise
@ -500,7 +499,7 @@ SWITCH_DECLARE(void) switch_rtp_set_cng_pt(switch_rtp_t *rtp_session, switch_pay
\return the pointer to the private data
*/
SWITCH_DECLARE(void *) switch_rtp_get_private(switch_rtp_t *rtp_session);
SWITCH_DECLARE(switch_status_t) switch_rtp_set_payload_map(switch_rtp_t *rtp_session, payload_map_t **pmap);
SWITCH_DECLARE(void) switch_rtp_intentional_bugs(switch_rtp_t *rtp_session, switch_rtp_bug_flag_t bugs);
SWITCH_DECLARE(switch_rtp_stats_t *) switch_rtp_get_stats(switch_rtp_t *rtp_session, switch_memory_pool_t *pool);

View File

@ -184,7 +184,8 @@ typedef enum {
MFLAG_NOMOH = (1 << 19),
MFLAG_VIDEO_BRIDGE = (1 << 20),
MFLAG_INDICATE_MUTE_DETECT = (1 << 21),
MFLAG_PAUSE_RECORDING = (1 << 22)
MFLAG_PAUSE_RECORDING = (1 << 22),
MFLAG_ACK_VIDEO = (1 << 23)
} member_flag_t;
typedef enum {
@ -1796,6 +1797,10 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe
channel = switch_core_session_get_channel(member->session);
if (switch_channel_test_flag(channel, CF_VIDEO)) {
switch_set_flag_locked(member, MFLAG_ACK_VIDEO);
}
switch_channel_set_variable_printf(channel, "conference_member_id", "%d", member->id);
switch_channel_set_variable_printf(channel, "conference_moderator", "%s", switch_test_flag(member, MFLAG_MOD) ? "true" : "false");
switch_channel_set_variable(channel, "conference_recording", conference->record_filename);
@ -2595,6 +2600,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
char *rfile = switch_channel_expand_variables(channel, conference->auto_record);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Auto recording file: %s\n", rfile);
launch_conference_record_thread(conference, rfile, SWITCH_TRUE);
if (rfile != conference->auto_record) {
conference->record_filename = switch_core_strdup(conference->pool, rfile);
switch_safe_free(rfile);
@ -3639,6 +3645,12 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
break;
}
if (switch_channel_test_flag(channel, CF_VIDEO) && !switch_test_flag(member, MFLAG_ACK_VIDEO)) {
switch_set_flag_locked(member, MFLAG_ACK_VIDEO);
switch_channel_clear_flag(channel, CF_VIDEO_ECHO);
switch_core_session_refresh_video(member->session);
}
/* if we have caller digits, feed them to the parser to find an action */
if (switch_channel_has_dtmf(channel)) {
char dtmf[128] = "";
@ -8410,8 +8422,8 @@ SWITCH_STANDARD_APP(conference_function)
msg.from = __FILE__;
/* Tell the channel we are going to be in a bridge */
msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
switch_core_session_receive_message(session, &msg);
//msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE;
//switch_core_session_receive_message(session, &msg);
/* Run the conference loop */
conference_loop_output(&member);

View File

@ -83,9 +83,21 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_vp8_load)
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_CODEC(codec_interface, "VP8 Video (passthru)");
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_VIDEO, 99, "VP8", NULL, 90000, 90000, 0,
0, 0, 0, 0, 1, 1, switch_vp8_init, switch_vp8_encode, switch_vp8_decode, switch_vp8_destroy);
SWITCH_ADD_CODEC(codec_interface, "red Video (passthru)");
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_VIDEO, 103, "red", NULL, 90000, 90000, 0,
0, 0, 0, 0, 1, 1, switch_vp8_init, switch_vp8_encode, switch_vp8_decode, switch_vp8_destroy);
SWITCH_ADD_CODEC(codec_interface, "ulpfec Video (passthru)");
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_VIDEO, 103, "ulpfec", NULL, 90000, 90000, 0,
0, 0, 0, 0, 1, 1, switch_vp8_init, switch_vp8_encode, switch_vp8_decode, switch_vp8_destroy);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}

View File

@ -626,13 +626,14 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY nomedia - sending ack\n");
nua_ack(tech_pvt->nh,
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_RTP_SELECT(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
TAG_END());
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_RTP_SELECT(1),
SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
TAG_END());
sofia_clear_flag(tech_pvt, TFLAG_3PCC_INVITE); // all done
sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
sofia_set_flag_locked(tech_pvt, TFLAG_SDP);
@ -667,7 +668,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
tech_pvt->mparams.local_sdp_str = NULL;
switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0);
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
} else {
switch_core_media_set_local_sdp(session, b_sdp, SWITCH_TRUE);
@ -683,12 +684,14 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_RESPONSE_HEADER_PREFIX);
if (sofia_use_soa(tech_pvt)) {
nua_respond(tech_pvt->nh, SIP_200_OK,
TAG_IF(is_proxy, NUTAG_AUTOANSWER(0)),
SIPTAG_CONTACT_STR(tech_pvt->profile->url),
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
SOATAG_REUSE_REJECTED(1), TAG_IF(is_proxy, SOATAG_RTP_SELECT(1)),
SOATAG_REUSE_REJECTED(1),
SOATAG_RTP_SELECT(1),
SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
@ -762,7 +765,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
return status;
}
switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0);
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
}
@ -834,7 +837,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
SOATAG_REUSE_REJECTED(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"),
TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)),
TAG_IF(is_proxy, SOATAG_RTP_SELECT(1)),
SOATAG_RTP_SELECT(1),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
@ -1221,7 +1224,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
switch_channel_set_flag(tech_pvt->channel, CF_SECURE);
}
if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING) || sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_PT)) {
if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING)) {
switch_core_media_reset_autofix(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
}
}
@ -1264,7 +1267,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
ip = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE);
port = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE);
if (ip && port) {
switch_core_media_gen_local_sdp(session, ip, (switch_port_t)atoi(port), msg->string_arg, 1);
switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, ip, (switch_port_t)atoi(port), msg->string_arg, 1);
}
if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
@ -1397,7 +1400,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
goto end_lock;
}
}
switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 1);
switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1);
if (send_invite) {
if (!switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
@ -2081,7 +2084,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
goto end_lock;
}
switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0);
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
}

View File

@ -513,7 +513,7 @@ static switch_status_t channel_receive_event(switch_core_session_t *session, swi
}
switch_rtp_set_default_payload(tech_pvt->rtp_session, pt);
switch_rtp_set_recv_pt(tech_pvt->rtp_session, pt);
//switch_rtp_set_recv_pt(tech_pvt->rtp_session, pt);
}
if (compare_var(event, channel, kRFC2833PT)) {

View File

@ -3743,7 +3743,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
sofia_set_pflag(profile, PFLAG_DISABLE_100REL);
profile->auto_restart = 1;
sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING);
sofia_set_media_flag(profile, SCMF_AUTOFIX_PT);
sofia_set_media_flag(profile, SCMF_RENEG_ON_REINVITE);
sofia_set_media_flag(profile, SCMF_RTP_AUTOFLUSH_DURING_BRIDGE);
profile->contact_user = SOFIA_DEFAULT_CONTACT_USER;
sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID);
@ -4381,12 +4381,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
} else {
sofia_clear_media_flag(profile, SCMF_AUTOFIX_TIMING);
}
} else if (!strcasecmp(var, "rtp-autofix-pt")) {
if (switch_true(val)) {
sofia_set_media_flag(profile, SCMF_AUTOFIX_PT);
} else {
sofia_clear_media_flag(profile, SCMF_AUTOFIX_PT);
}
} else if (!strcasecmp(var, "contact-user")) {
profile->contact_user = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "nat-options-ping")) {
@ -5250,7 +5244,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
sofia_update_callee_id(session, profile, sip, SWITCH_FALSE);
if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING) || sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_PT)) {
if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING)) {
switch_core_media_reset_autofix(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO);
}
@ -6204,7 +6198,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
} else {
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP");
switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0);
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);
switch_channel_set_state(channel, CS_HIBERNATE);
if (sofia_use_soa(tech_pvt)) {
@ -6321,7 +6315,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
goto done;
}
}
switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 1);
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 1);
if (sofia_use_soa(tech_pvt)) {
nua_respond(tech_pvt->nh, SIP_200_OK,
@ -6427,7 +6421,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
goto done;
}
switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0);
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite RTP Error!\n");
@ -6446,7 +6440,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (is_ok) {
if (switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0);
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
}
if (sofia_use_soa(tech_pvt)) {
nua_respond(tech_pvt->nh, SIP_200_OK,
@ -6486,7 +6480,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) {
goto done;
}
switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0);
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n");
switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);

View File

@ -752,7 +752,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
}
if (!switch_channel_get_private(tech_pvt->channel, "t38_options") || zstr(tech_pvt->mparams.local_sdp_str)) {
switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0);
switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0);
}
sofia_set_flag_locked(tech_pvt, TFLAG_READY);

View File

@ -644,8 +644,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
default:
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s decoder error! [%d]\n",
session->read_codec->codec_interface->interface_name, status);
goto done;
if (++session->decoder_errors < 10) {
status = SWITCH_STATUS_SUCCESS;
} else {
goto done;
}
}
session->decoder_errors = 0;
}
if (session->bugs) {

File diff suppressed because it is too large Load Diff

View File

@ -325,7 +325,6 @@ struct switch_rtp {
int8_t sending_dtmf;
uint8_t need_mark;
switch_payload_t payload;
switch_payload_t rpayload;
switch_rtp_invalid_handler_t invalid_handler;
void *private_data;
uint32_t ts;
@ -398,6 +397,10 @@ struct switch_rtp {
switch_size_t last_flush_packet_count;
uint32_t interdigit_delay;
switch_core_session_t *session;
payload_map_t **pmaps;
payload_map_t *pmap_tail;
int pmap_ttl;
#ifdef ENABLE_ZRTP
zrtp_session_t *zrtp_session;
zrtp_profile_t *zrtp_profile;
@ -1859,6 +1862,19 @@ SWITCH_DECLARE(switch_port_t) switch_rtp_request_port(const char *ip)
return port;
}
SWITCH_DECLARE(switch_status_t) switch_rtp_set_payload_map(switch_rtp_t *rtp_session, payload_map_t **pmap)
{
if (rtp_session) {
switch_mutex_lock(rtp_session->flag_mutex);
rtp_session->pmaps = pmap;
switch_mutex_unlock(rtp_session->flag_mutex);
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
SWITCH_DECLARE(void) switch_rtp_intentional_bugs(switch_rtp_t *rtp_session, switch_rtp_bug_flag_t bugs)
{
rtp_session->rtp_bugs = bugs;
@ -2973,7 +2989,6 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session
rtp_session->recv_msg.header.cc = 0;
rtp_session->payload = payload;
rtp_session->rpayload = payload;
switch_rtp_set_interval(rtp_session, ms_per_packet, samples_per_interval);
rtp_session->conf_samples_per_interval = samples_per_interval;
@ -3164,11 +3179,6 @@ SWITCH_DECLARE(void) switch_rtp_set_telephony_recv_event(switch_rtp_t *rtp_sessi
}
}
SWITCH_DECLARE(void) switch_rtp_set_recv_pt(switch_rtp_t *rtp_session, switch_payload_t pt)
{
rtp_session->rpayload = pt;
}
SWITCH_DECLARE(void) switch_rtp_set_cng_pt(switch_rtp_t *rtp_session, switch_payload_t pt)
{
@ -4063,6 +4073,27 @@ static int jb_valid(switch_rtp_t *rtp_session)
return 1;
}
static int check_recv_payload(switch_rtp_t *rtp_session)
{
int ok = 0;
if (rtp_session->pmaps && *rtp_session->pmaps) {
payload_map_t *pmap;
switch_mutex_lock(rtp_session->flag_mutex);
for (pmap = *rtp_session->pmaps; pmap && pmap->allocated; pmap = pmap->next) {
if (!pmap->negotiated) {
continue;
}
if (rtp_session->recv_msg.header.pt == pmap->pt) {
ok = 1;
}
}
switch_mutex_unlock(rtp_session->flag_mutex);
}
return ok;
}
#define return_cng_frame() do_cng = 1; goto timer_check
static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes, switch_frame_flag_t *flags, switch_bool_t return_jb_packet)
@ -4149,7 +4180,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
if (status == SWITCH_STATUS_SUCCESS && *bytes) {
if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) {
*flags &= ~SFF_RTCP;
if (rtp_session->recv_msg.header.pt != rtp_session->rpayload &&
if (!check_recv_payload(rtp_session) &&
(!rtp_session->recv_te || rtp_session->recv_msg.header.pt != rtp_session->recv_te) &&
(!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) &&
rtp_session->rtcp_recv_msg_p->header.version == 2 &&
@ -4319,7 +4350,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
#ifdef ENABLE_SRTP
if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] && rtp_session->recv_msg.header.version == 2 &&
((rtp_session->recv_msg.header.pt == rtp_session->rpayload) ||
(check_recv_payload(rtp_session) ||
(rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) ||
(rtp_session->cng_pt && rtp_session->recv_msg.header.pt == rtp_session->cng_pt))) {
//if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] && (!rtp_session->ice.ice_user || rtp_session->recv_msg.header.version == 2)) {
@ -4376,7 +4407,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
rtp_session->last_read_ts = ts;
}
if (rtp_session->flags[SWITCH_RTP_FLAG_BYTESWAP] && rtp_session->recv_msg.header.pt == rtp_session->rpayload) {
if (rtp_session->flags[SWITCH_RTP_FLAG_BYTESWAP] && check_recv_payload(rtp_session)) {
switch_swap_linear((int16_t *)RTP_BODY(rtp_session), (int) *bytes - rtp_header_len);
}
@ -4602,7 +4633,8 @@ static int using_ice(switch_rtp_t *rtp_session)
return 0;
}
static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_type, switch_frame_flag_t *flags, switch_io_flag_t io_flags)
static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_type,
payload_map_t **pmapP, switch_frame_flag_t *flags, switch_io_flag_t io_flags)
{
switch_channel_t *channel = NULL;
@ -4969,11 +5001,33 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
!rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] && !rtp_session->flags[SWITCH_RTP_FLAG_UDPTL] &&
rtp_session->recv_msg.header.pt != 13 &&
rtp_session->recv_msg.header.pt != rtp_session->recv_te &&
(!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) &&
rtp_session->recv_msg.header.pt != rtp_session->rpayload &&
!(rtp_session->rtp_bugs & RTP_BUG_ACCEPT_ANY_PAYLOAD) && !(rtp_session->rtp_bugs & RTP_BUG_ACCEPT_ANY_PACKETS)) {
/* drop frames of incorrect payload number and return CNG frame instead */
return_cng_frame();
(!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt)) {
int accept_packet = 0;
if (rtp_session->pmaps && *rtp_session->pmaps) {
payload_map_t *pmap;
switch_mutex_lock(rtp_session->flag_mutex);
for (pmap = *rtp_session->pmaps; pmap && pmap->allocated; pmap = pmap->next) {
if (!pmap->negotiated) {
continue;
}
if (rtp_session->recv_msg.header.pt == pmap->pt) {
accept_packet = 1;
if (pmapP) {
*pmapP = pmap;
}
}
}
switch_mutex_unlock(rtp_session->flag_mutex);
}
if (!accept_packet &&
!(rtp_session->rtp_bugs & RTP_BUG_ACCEPT_ANY_PAYLOAD) && !(rtp_session->rtp_bugs & RTP_BUG_ACCEPT_ANY_PACKETS)) {
/* drop frames of incorrect payload number and return CNG frame instead */
return_cng_frame();
}
}
if (!bytes && (io_flags & SWITCH_IO_FLAG_NOBLOCK)) {
@ -5085,7 +5139,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
if (rtp_session->flags[SWITCH_RTP_FLAG_UDPTL]) {
#if 0
if (rtp_session->recv_msg.header.version == 2 && rtp_session->recv_msg.header.pt == rtp_session->rpayload) {
if (rtp_session->recv_msg.header.version == 2 && check_recv_payload(rtp_session)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING,
"Ignoring udptl packet of size of %ld bytes that looks strikingly like a RTP packet.\n", (long)bytes);
bytes = 0;
@ -5335,7 +5389,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_read(switch_rtp_t *rtp_session, void
return SWITCH_STATUS_FALSE;
}
bytes = rtp_common_read(rtp_session, payload_type, flags, io_flags);
bytes = rtp_common_read(rtp_session, payload_type, NULL, flags, io_flags);
if (bytes < 0) {
*datalen = 0;
@ -5415,7 +5469,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp
return SWITCH_STATUS_FALSE;
}
bytes = rtp_common_read(rtp_session, &frame->payload, &frame->flags, io_flags);
bytes = rtp_common_read(rtp_session, &frame->payload, &frame->pmap, &frame->flags, io_flags);
frame->data = RTP_BODY(rtp_session);
frame->packet = &rtp_session->recv_msg;
@ -5504,7 +5558,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read(switch_rtp_t *rtp_sessi
return SWITCH_STATUS_FALSE;
}
bytes = rtp_common_read(rtp_session, payload_type, flags, io_flags);
bytes = rtp_common_read(rtp_session, payload_type, NULL, flags, io_flags);
*data = RTP_BODY(rtp_session);
if (bytes < 0) {
@ -6146,12 +6200,26 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
rtp_session->stats.outbound.packet_count++;
}
if (frame->pmap && rtp_session->pmaps && *rtp_session->pmaps && rtp_session->pmap_ttl > 1) {
payload_map_t *pmap;
switch_mutex_lock(rtp_session->flag_mutex);
for (pmap = *rtp_session->pmaps; pmap; pmap = pmap->next) {
if (pmap->hash == frame->pmap->hash && !strcmp(pmap->iananame, frame->pmap->iananame)) {
payload = pmap->recv_pt;
break;
}
}
switch_mutex_unlock(rtp_session->flag_mutex);
}
if (fwd) {
send_msg = frame->packet;
len = frame->packetlen;
ts = 0;
// Trying this based on http://jira.freeswitch.org/browse/MODSOFIA-90
//if (frame->codec && frame->codec->agreed_pt == frame->payload) {
send_msg->header.pt = payload;
//}
} else {

View File

@ -114,7 +114,7 @@ SWITCH_DECLARE(switch_status_t) switch_frame_dup(switch_frame_t *orig, switch_fr
memcpy(new_frame->data, orig->data, orig->datalen);
new_frame->codec = NULL;
new_frame->pmap = NULL;
*clone = new_frame;
return SWITCH_STATUS_SUCCESS;