refactor some of the video passthru code

This commit is contained in:
Anthony Minessale 2013-06-17 19:52:37 -05:00
parent 3ac4e77384
commit 2fac3a8e83
14 changed files with 705 additions and 530 deletions

View File

@ -2555,6 +2555,7 @@ SWITCH_DECLARE(int) switch_core_gen_certs(const char *prefix);
SWITCH_DECLARE(int) switch_core_cert_gen_fingerprint(const char *prefix, dtls_fingerprint_t *fp);
SWITCH_DECLARE(int) switch_core_cert_expand_fingerprint(dtls_fingerprint_t *fp, const char *str);
SWITCH_DECLARE(int) switch_core_cert_verify(dtls_fingerprint_t *fp);
SWITCH_DECLARE(switch_status_t) switch_core_session_refresh_video(switch_core_session_t *session);
SWITCH_END_EXTERN_C
#endif

View File

@ -255,6 +255,7 @@ SWITCH_DECLARE(void) switch_core_session_set_ice(switch_core_session_t *session)
SWITCH_DECLARE(void) switch_core_media_init(void);
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_END_EXTERN_C
#endif

View File

@ -500,9 +500,6 @@ SWITCH_DECLARE(void) switch_rtp_set_cng_pt(switch_rtp_t *rtp_session, switch_pay
*/
SWITCH_DECLARE(void *) switch_rtp_get_private(switch_rtp_t *rtp_session);
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_stun_ping(switch_rtp_t *rtp_session, const char *stun_ip, switch_port_t stun_port,
uint32_t packet_count, switch_bool_t funny);
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);
@ -512,6 +509,7 @@ SWITCH_DECLARE(void) switch_rtp_set_interdigit_delay(switch_rtp_t *rtp_session,
SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, dtls_fingerprint_t *local_fp, dtls_fingerprint_t *remote_fp, dtls_type_t type);
SWITCH_DECLARE(int) switch_rtp_has_dtls(void);
SWITCH_DECLARE(void) switch_rtp_video_refresh(switch_rtp_t *rtp_session);
/*!
\}

View File

@ -1324,6 +1324,7 @@ typedef enum {
CF_DTLS,
CF_VERBOSE_SDP,
CF_DTLS_OK,
CF_VIDEO_PASSIVE,
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
/* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
CF_FLAG_MAX

View File

@ -1443,7 +1443,10 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe
conference_send_presence(conference);
channel = switch_core_session_get_channel(member->session);
switch_channel_set_flag(channel, CF_VIDEO_PASSIVE);
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);
@ -1670,6 +1673,7 @@ static switch_status_t conference_del_member(conference_obj_t *conference, confe
}
}
switch_channel_clear_flag(channel, CF_VIDEO_PASSIVE);
conference_send_presence(conference);
switch_channel_set_variable(channel, "conference_call_key", NULL);

View File

@ -116,6 +116,8 @@ SWITCH_STANDARD_APP(record_fsv_function)
int count = 0, sanity = 30;
switch_core_session_message_t msg = { 0 };
switch_channel_set_flag(channel, CF_VIDEO_PASSIVE);
/* Tell the channel to request a fresh vid frame */
msg.from = __FILE__;
msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ;
@ -138,7 +140,7 @@ SWITCH_STANDARD_APP(record_fsv_function)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s timeout waiting for video.\n",
switch_channel_get_name(channel));
switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "Got timeout while waiting for video");
return;
goto done;
}
}
}
@ -146,13 +148,13 @@ SWITCH_STANDARD_APP(record_fsv_function)
if (!switch_channel_ready(channel)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s not ready.\n", switch_channel_get_name(channel));
switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "Channel not ready");
return;
goto done;
}
if ((fd = open((char *) data, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR)) < 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error opening file %s\n", (char *) data);
switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "Got error while opening file");
return;
goto done;
}
if (switch_core_codec_init(&codec,
@ -284,6 +286,10 @@ SWITCH_STANDARD_APP(record_fsv_function)
switch_core_session_set_read_codec(session, NULL);
switch_core_codec_destroy(&codec);
done:
switch_channel_clear_flag(channel, CF_VIDEO_PASSIVE);
}
SWITCH_STANDARD_APP(play_fsv_function)
@ -306,6 +312,8 @@ SWITCH_STANDARD_APP(play_fsv_function)
switch_codec_implementation_t read_impl = { 0 };
switch_core_session_message_t msg = { 0 };
switch_channel_set_flag(channel, CF_VIDEO_PASSIVE);
/* Tell the channel to request a fresh vid frame */
msg.from = __FILE__;
msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ;
@ -322,7 +330,7 @@ SWITCH_STANDARD_APP(play_fsv_function)
if ((fd = open((char *) data, O_RDONLY | O_BINARY)) < 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error opening file %s\n", (char *) data);
switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "Got error while opening file");
return;
goto done;
}
if (read(fd, &h, sizeof(h)) != sizeof(h)) {
@ -504,6 +512,9 @@ SWITCH_STANDARD_APP(play_fsv_function)
if (fd > -1) {
close(fd);
}
done:
switch_channel_clear_flag(channel, CF_VIDEO_PASSIVE);
}
struct fsv_file_context {

View File

@ -1279,7 +1279,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
}
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/media_control+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END());
}
break;
case SWITCH_MESSAGE_INDICATE_BROADCAST:

View File

@ -1922,6 +1922,11 @@ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch
if (flag == CF_RECOVERED) {
switch_channel_set_variable(channel, "recovered", NULL);
}
if (flag == CF_VIDEO_PASSIVE) {
switch_core_session_wake_video_thread(channel->session);
}
}

View File

@ -98,6 +98,13 @@ typedef struct codec_params_s {
} codec_params_t;
struct media_helper {
switch_core_session_t *session;
switch_thread_cond_t *cond;
switch_mutex_t *cond_mutex;
int up;
};
typedef struct switch_rtp_engine_s {
switch_secure_settings_t ssec;
switch_media_type_t type;
@ -147,7 +154,8 @@ typedef struct switch_rtp_engine_s {
char *remote_rtcp_ice_addr;
switch_port_t remote_rtcp_ice_port;
struct media_helper mh;
switch_thread_t *media_thread;
} switch_rtp_engine_t;
@ -508,7 +516,6 @@ SWITCH_DECLARE(const char *) switch_core_session_local_crypto_key(switch_core_se
}
return session->media_handle->engines[type].ssec.local_crypto_key;
}
@ -2133,6 +2140,7 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_NOTICE,
"setting remote %s ice addr to %s:%d based on candidate\n", type2str(type),
engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port);
engine->ice_in.cands[engine->ice_in.chosen[0]][0].ready++;
engine->remote_rtp_ice_port = (switch_port_t) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port;
engine->remote_rtp_ice_addr = switch_core_session_strdup(smh->session, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
@ -2157,7 +2165,7 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_
}
if (!got_rtcp_mux) {
if (m && !got_rtcp_mux) {
engine->rtcp_mux = -1;
}
@ -2179,8 +2187,8 @@ SWITCH_DECLARE(void) switch_core_session_set_ice(switch_core_session_t *session)
switch_channel_set_flag(session->channel, CF_VERBOSE_SDP);
switch_channel_set_flag(session->channel, CF_WEBRTC);
switch_channel_set_flag(session->channel, CF_ICE);
smh->mparams->rtcp_audio_interval_msec = "5000";
smh->mparams->rtcp_video_interval_msec = "5000";
smh->mparams->rtcp_audio_interval_msec = "10000";
smh->mparams->rtcp_video_interval_msec = "10000";
}
//?
@ -2376,6 +2384,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
switch_core_media_pass_zrtp_hash(session);
check_ice(smh, SWITCH_MEDIA_TYPE_AUDIO, sdp, NULL);
check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, NULL);
for (m = sdp->sdp_media; m; m = m->m_next) {
sdp_connection_t *connection;
@ -2945,7 +2954,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
if (!strcasecmp(attr->a_name, "framerate") && attr->a_value) {
//framerate = atoi(attr->a_value);
}
if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value) {
if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value && !strcmp(attr->a_value, "1")) {
switch_channel_set_variable(session->channel, "rtp_remote_video_rtcp_port", attr->a_value);
v_engine->remote_rtcp_port = (switch_port_t)atoi(attr->a_value);
} else if (!got_video_crypto && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) {
@ -3038,7 +3047,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
if (!match && vmatch) match = 1;
check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, m);
check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, NULL);
//check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, NULL);
break;
} else {
vmatch = 0;
@ -3562,6 +3571,14 @@ SWITCH_DECLARE(void) switch_core_media_deactivate_rtp(switch_core_session_t *ses
a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
if (v_engine->media_thread) {
switch_status_t st;
switch_channel_clear_flag(session->channel, CF_VIDEO_PASSIVE);
v_engine->mh.up = 0;
switch_thread_join(&st, v_engine->media_thread);
v_engine->media_thread = NULL;
}
if (v_engine->rtp_session) {
switch_rtp_destroy(&v_engine->rtp_session);
@ -3608,7 +3625,7 @@ static void gen_ice(switch_core_session_t *session, switch_media_type_t type, co
engine = &smh->engines[type];
#ifdef RTCP_MUX
if (!engine->rtcp_mux && type == SWITCH_MEDIA_TYPE_AUDIO) {
if (!engine->rtcp_mux) {// && type == SWITCH_MEDIA_TYPE_AUDIO) {
engine->rtcp_mux = SWITCH_TRUE;
}
#endif
@ -3665,6 +3682,100 @@ static void gen_ice(switch_core_session_t *session, switch_media_type_t type, co
}
SWITCH_DECLARE(void) switch_core_session_wake_video_thread(switch_core_session_t *session)
{
switch_media_handle_t *smh;
switch_rtp_engine_t *v_engine;
if (!(smh = session->media_handle)) {
return;
}
v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
if (!v_engine->rtp_session) {
return;
}
if (switch_mutex_trylock(v_engine->mh.cond_mutex) == SWITCH_STATUS_SUCCESS) {
switch_thread_cond_broadcast(v_engine->mh.cond);
switch_mutex_unlock(v_engine->mh.cond_mutex);
}
}
static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, void *obj)
{
struct media_helper *mh = obj;
switch_core_session_t *session = mh->session;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_status_t status;
switch_frame_t *read_frame;
switch_media_handle_t *smh;
if (!(smh = session->media_handle)) {
return NULL;
}
switch_core_session_read_lock(session);
mh->up = 1;
switch_mutex_lock(mh->cond_mutex);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread started\n", switch_channel_get_name(session->channel));
switch_core_session_refresh_video(session);
while (switch_channel_up_nosig(channel)) {
if (switch_channel_test_flag(channel, CF_VIDEO_PASSIVE)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread paused\n", switch_channel_get_name(session->channel));
switch_thread_cond_wait(mh->cond, mh->cond_mutex);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread resumed\n", switch_channel_get_name(session->channel));
switch_core_session_refresh_video(session);
}
if (switch_channel_test_flag(channel, CF_VIDEO_PASSIVE)) {
continue;
}
if (!switch_channel_media_up(session->channel)) {
switch_yield(10000);
continue;
}
status = switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
if (!SWITCH_READ_ACCEPTABLE(status)) {
switch_cond_next();
continue;
}
if (switch_channel_test_flag(channel, CF_VIDEO_REFRESH_REQ)) {
switch_core_session_refresh_video(session);
switch_channel_clear_flag(channel, CF_VIDEO_REFRESH_REQ);
}
if (switch_test_flag(read_frame, SFF_CNG)) {
continue;
}
switch_core_session_write_video_frame(session, read_frame, SWITCH_IO_FLAG_NONE, 0);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread ended\n", switch_channel_get_name(session->channel));
switch_mutex_unlock(mh->cond_mutex);
switch_core_session_rwunlock(session);
mh->up = 0;
return NULL;
}
//?
@ -3902,7 +4013,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
uint8_t vad_in = (smh->mparams->vflags & VAD_IN);
uint8_t vad_out = (smh->mparams->vflags & VAD_OUT);
uint8_t inb = switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND;
uint32_t stun_ping = 0;
const char *ssrc;
//switch_core_media_set_rtp_session(session, SWITCH_MEDIA_TYPE_AUDIO, a_engine->rtp_session);
@ -3934,17 +4044,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
vad_out = 0;
}
if ((smh->mparams->stun_flags & STUN_FLAG_SET) && (val = switch_channel_get_variable(session->channel, "rtp_stun_ping"))) {
int ival = atoi(val);
if (ival <= 0) {
if (switch_true(val)) {
ival = 6;
}
}
stun_ping = (ival * a_engine->read_impl.samples_per_second) / a_engine->read_impl.samples_per_packet;
}
a_engine->ssrc = switch_rtp_get_ssrc(a_engine->rtp_session);
switch_channel_set_variable_printf(session->channel, "rtp_use_ssrc", "%u", a_engine->ssrc);
@ -3968,14 +4067,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
switch_channel_get_name(switch_core_session_get_channel(session)), vad_in ? "in" : "", vad_out ? "out" : "");
}
if (stun_ping) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting stun ping to %s:%d\n", smh->mparams->stun_ip, stun_ping);
switch_rtp_activate_stun_ping(a_engine->rtp_session, smh->mparams->stun_ip, smh->mparams->stun_port, stun_ping,
(smh->mparams->stun_flags & STUN_FLAG_FUNNY) ? 1 : 0);
}
if (a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0].ready) {
@ -3991,10 +4082,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
IPR_RTP,
#ifdef GOOGLE_ICE
ICE_GOOGLE_JINGLE,
NULL,
NULL
#else
switch_channel_direction(session->channel) ==
SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : ICE_VANILLA | ICE_CONTROLLED,
SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : (ICE_VANILLA | ICE_CONTROLLED),
&a_engine->ice_in
#endif
);
@ -4018,36 +4109,42 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
switch_rtp_activate_rtcp(a_engine->rtp_session, -1, remote_rtcp_port, a_engine->rtcp_mux > 0);
} else {
int interval = atoi(val);
if (interval < 100 || interval > 5000) {
if (interval < 100 || interval > 500000) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
"Invalid rtcp interval spec [%d] must be between 100 and 5000\n", interval);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating RTCP PORT %d\n", remote_rtcp_port);
switch_rtp_activate_rtcp(a_engine->rtp_session, interval, remote_rtcp_port, a_engine->rtcp_mux > 0);
"Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
interval = 10000;
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating RTCP PORT %d\n", remote_rtcp_port);
switch_rtp_activate_rtcp(a_engine->rtp_session, interval, remote_rtcp_port, a_engine->rtcp_mux > 0);
}
if (a_engine->ice_in.cands[a_engine->ice_in.chosen[1]][1].ready) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating RTCP ICE\n");
if (!strcmp(a_engine->ice_in.cands[a_engine->ice_in.chosen[1]][1].con_addr, a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0].con_addr)
&& a_engine->ice_in.cands[a_engine->ice_in.chosen[1]][1].con_port == a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0].con_port) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Skipping RTCP ICE (Same as RTP)\n");
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating RTCP ICE\n");
switch_rtp_activate_ice(a_engine->rtp_session,
a_engine->ice_in.ufrag,
a_engine->ice_out.ufrag,
a_engine->ice_out.pwd,
a_engine->ice_in.pwd,
IPR_RTCP,
switch_rtp_activate_ice(a_engine->rtp_session,
a_engine->ice_in.ufrag,
a_engine->ice_out.ufrag,
a_engine->ice_out.pwd,
a_engine->ice_in.pwd,
IPR_RTCP,
#ifdef GOOGLE_ICE
ICE_GOOGLE_JINGLE,
NULL
ICE_GOOGLE_JINGLE,
NULL
#else
switch_channel_direction(session->channel) ==
SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : ICE_VANILLA | ICE_CONTROLLED,
&a_engine->ice_in
switch_channel_direction(session->channel) ==
SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : (ICE_VANILLA | ICE_CONTROLLED),
&a_engine->ice_in
#endif
);
}
}
}
if (!zstr(a_engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls() && dtls_ok(smh->session)) {
@ -4364,8 +4461,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
if (switch_rtp_ready(v_engine->rtp_session)) {
switch_threadattr_t *thd_attr = NULL;
switch_memory_pool_t *pool = switch_core_session_get_pool(session);
switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->codec_params.agreed_pt);
//switch_core_media_set_rtp_session(session, SWITCH_MEDIA_TYPE_VIDEO, v_engine->rtp_session);
v_engine->mh.session = session;
switch_threadattr_create(&thd_attr, pool);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_thread_cond_create(&v_engine->mh.cond, pool);
switch_mutex_init(&v_engine->mh.cond_mutex, SWITCH_MUTEX_NESTED, pool);
switch_thread_create(&v_engine->media_thread, thd_attr, video_helper_thread, &v_engine->mh, switch_core_session_get_pool(session));
}
if (switch_rtp_ready(v_engine->rtp_session)) {
@ -4378,14 +4484,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
} else {
switch_rtp_set_ssrc(v_engine->rtp_session, v_engine->ssrc);
}
if (v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].ready) {
gen_ice(session, SWITCH_MEDIA_TYPE_VIDEO, NULL, 0);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating Video ICE\n");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating Video ICE\n");
switch_rtp_activate_ice(v_engine->rtp_session,
v_engine->ice_in.ufrag,
v_engine->ice_out.ufrag,
@ -4396,17 +4501,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
ICE_GOOGLE_JINGLE,
NULL
#else
ICE_VANILLA | ICE_CONTROLLED,
switch_channel_direction(session->channel) ==
SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : (ICE_VANILLA | ICE_CONTROLLED),
&v_engine->ice_in
#endif
);
}
if ((val = switch_channel_get_variable(session->channel, "rtcp_video_interval_msec")) || (val = smh->mparams->rtcp_video_interval_msec)) {
const char *rport = switch_channel_get_variable(session->channel, "rtp_remote_video_rtcp_port");
switch_port_t remote_port = v_engine->remote_rtcp_port;
if (rport) {
remote_port = (switch_port_t)atoi(rport);
}
@ -4415,40 +4522,49 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
switch_rtp_activate_rtcp(v_engine->rtp_session, -1, remote_port, v_engine->rtcp_mux > 0);
} else {
int interval = atoi(val);
if (interval < 100 || interval > 5000) {
if (interval < 100 || interval > 500000) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
"Invalid rtcp interval spec [%d] must be between 100 and 5000\n", interval);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating VIDEO RTCP PORT %d\n", remote_port);
switch_rtp_activate_rtcp(v_engine->rtp_session, interval, remote_port, v_engine->rtcp_mux > 0);
"Invalid rtcp interval spec [%d] must be between 100 and 500000\n", interval);
}
interval = 10000;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating VIDEO RTCP PORT %d mux %d\n", remote_port, v_engine->rtcp_mux);
switch_rtp_activate_rtcp(v_engine->rtp_session, interval, remote_port, v_engine->rtcp_mux > 0);
}
if (v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].ready) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating VIDEO RTCP ICE\n");
switch_rtp_activate_ice(v_engine->rtp_session,
v_engine->ice_in.ufrag,
v_engine->ice_out.ufrag,
v_engine->ice_out.pwd,
v_engine->ice_in.pwd,
IPR_RTCP,
#ifdef GOOGLE_ICE
ICE_GOOGLE_JINGLE,
NULL
#else
switch_channel_direction(session->channel) ==
SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : ICE_VANILLA | ICE_CONTROLLED,
&v_engine->ice_in
#endif
);
}
}
if (!strcmp(v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].con_addr, v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].con_addr)
&& v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].con_port == v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].con_port) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Skipping VIDEO RTCP ICE (Same as VIDEO RTP)\n");
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating VIDEO RTCP ICE\n");
switch_rtp_activate_ice(v_engine->rtp_session,
v_engine->ice_in.ufrag,
v_engine->ice_out.ufrag,
v_engine->ice_out.pwd,
v_engine->ice_in.pwd,
IPR_RTCP,
#ifdef GOOGLE_ICE
ICE_GOOGLE_JINGLE,
NULL
#else
switch_channel_direction(session->channel) ==
SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : (ICE_VANILLA | ICE_CONTROLLED),
&v_engine->ice_in
#endif
);
}
}
}
if (!zstr(v_engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls() && dtls_ok(smh->session)) {
dtls_type_t xtype,
dtype = switch_channel_direction(smh->session->channel) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER;
@ -4711,8 +4827,8 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen,
char tmp2[11] = "";
uint32_t c1 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 1);
uint32_t c2 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 2);
uint32_t c3 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 1);
uint32_t c4 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 2);
//uint32_t c3 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 1);
//uint32_t c4 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 2);
ice_t *ice_out;
tmp1[10] = '\0';
@ -4744,7 +4860,7 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen,
&& a_engine->codec_params.local_sdp_port != ice_out->cands[0][0].con_port) {
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\n",
tmp2, ice_out->cands[0][0].transport, c3,
tmp2, ice_out->cands[0][0].transport, c2,
ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port,
a_engine->codec_params.local_sdp_ip, a_engine->codec_params.local_sdp_port
);
@ -4754,7 +4870,7 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen,
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\n",
tmp1, ice_out->cands[0][0].transport, c2,
tmp1, ice_out->cands[0][0].transport, c1,
ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
);
@ -4763,7 +4879,7 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen,
&& a_engine->codec_params.local_sdp_port != ice_out->cands[0][1].con_port) {
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx raddr %s rport %d generation 0\n",
tmp2, ice_out->cands[0][0].transport, c4,
tmp2, ice_out->cands[0][0].transport, c2,
ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1),
a_engine->codec_params.local_sdp_ip, a_engine->codec_params.local_sdp_port + (a_engine->rtcp_mux > 0 ? 0 : 1)
);
@ -4927,6 +5043,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
const char *pass_fmtp = switch_channel_get_variable(session->channel, "rtp_video_fmtp");
const char *ov_fmtp = switch_channel_get_variable(session->channel, "rtp_force_video_fmtp");
const char *append_audio = switch_channel_get_variable(session->channel, "rtp_append_audio_sdp");
const char *append_video = switch_channel_get_variable(session->channel, "rtp_append_video_sdp");
char srbuf[128] = "";
const char *var_val;
const char *username;
@ -4942,6 +5059,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
switch_media_handle_t *smh;
ice_t *ice_out;
switch_assert(session);
if (!(smh = session->media_handle)) {
@ -5468,6 +5586,10 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fmtp:%d %s\n", v_engine->codec_params.pt, pass_fmtp);
}
if (append_video) {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s%s", append_video, end_of(append_video) == '\n' ? "" : "\n");
}
} else if (smh->mparams->num_codecs) {
int i;
int already_did[128] = { 0 };
@ -6211,6 +6333,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se
switch (msg->message_id) {
case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ:
{
if (v_engine->rtp_session) {
switch_rtp_video_refresh(v_engine->rtp_session);
}
}
break;
case SWITCH_MESSAGE_INDICATE_PROXY_MEDIA:
{
if (switch_rtp_ready(a_engine->rtp_session)) {

View File

@ -2867,6 +2867,22 @@ SWITCH_DECLARE(switch_log_level_t) switch_core_session_get_loglevel(switch_core_
return session->loglevel;
}
SWITCH_DECLARE(switch_status_t) switch_core_session_refresh_video(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
if (switch_channel_test_flag(channel, CF_VIDEO)) {
switch_core_session_message_t msg = { 0 };
msg.from = __FILE__;
msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ;
switch_core_session_receive_message(session, &msg);
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
/* For Emacs:
* Local Variables:
* mode:c

View File

@ -305,6 +305,7 @@ void switch_core_state_machine_init(switch_memory_pool_t *pool)
#define STATE_MACRO(__STATE, __STATE_STR) do { \
midstate = state; \
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) State %s\n", switch_channel_get_name(session->channel), __STATE_STR); \
switch_core_session_refresh_video(session);\
if (!driver_state_handler->on_##__STATE || (driver_state_handler->on_##__STATE(session) == SWITCH_STATUS_SUCCESS \
)) { \
while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler(session->channel, index++)) != 0) { \

View File

@ -625,52 +625,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear(switch_ivr_dmachine_t
}
#ifdef SWITCH_VIDEO_IN_THREADS
struct echo_helper {
switch_core_session_t *session;
int up;
};
static void *SWITCH_THREAD_FUNC echo_video_thread(switch_thread_t *thread, void *obj)
{
struct echo_helper *eh = obj;
switch_core_session_t *session = eh->session;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_status_t status;
switch_frame_t *read_frame;
switch_core_session_message_t msg = { 0 };
msg.from = __FILE__;
msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ;
switch_core_session_receive_message(session, &msg);
eh->up = 1;
while (switch_channel_ready(channel)) {
status = switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
if (switch_channel_test_flag(channel, CF_VIDEO_REFRESH_REQ)) {
switch_core_session_receive_message(session, &msg);
switch_channel_clear_flag(channel, CF_VIDEO_REFRESH_REQ);
}
if (!SWITCH_READ_ACCEPTABLE(status)) {
break;
}
if (switch_test_flag(read_frame, SFF_CNG)) {
continue;
}
switch_core_session_write_video_frame(session, read_frame, SWITCH_IO_FLAG_NONE, 0);
}
eh->up = 0;
return NULL;
}
#endif
SWITCH_DECLARE(switch_status_t) switch_ivr_session_echo(switch_core_session_t *session, switch_input_args_t *args)
{
@ -679,12 +633,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_echo(switch_core_session_t *s
switch_channel_t *channel = switch_core_session_get_channel(session);
int orig_vid = switch_channel_test_flag(channel, CF_VIDEO);
#ifdef SWITCH_VIDEO_IN_THREADS
struct echo_helper eh = { 0 };
switch_thread_t *thread;
switch_threadattr_t *thd_attr = NULL;
#endif
if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
@ -693,16 +641,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_echo(switch_core_session_t *s
restart:
#ifdef SWITCH_VIDEO_IN_THREADS
if (switch_channel_test_flag(channel, CF_VIDEO)) {
eh.session = session;
switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session));
switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_thread_create(&thread, thd_attr, echo_video_thread, &eh, switch_core_session_get_pool(session));
}
#endif
while (switch_channel_ready(channel)) {
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
if (!SWITCH_READ_ACCEPTABLE(status)) {
@ -775,14 +713,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_echo(switch_core_session_t *s
}
}
#ifdef SWITCH_VIDEO_IN_THREADS
if (eh.up) {
while (eh.up) {
switch_cond_next();
}
}
#endif
return SWITCH_STATUS_SUCCESS;
}

View File

@ -53,25 +53,58 @@ static void *SWITCH_THREAD_FUNC video_bridge_thread(switch_thread_t *thread, voi
switch_channel_t *b_channel = switch_core_session_get_channel(vh->session_b);
switch_status_t status;
switch_frame_t *read_frame;
const char *source = switch_channel_get_variable(channel, "source");
const char *b_source = switch_channel_get_variable(b_channel, "source");
switch_core_session_message_t msg = { 0 };
vh->up = 1;
while (switch_channel_ready(channel) && switch_channel_ready(b_channel) && vh->up == 1) {
status = switch_core_session_read_video_frame(vh->session_a, &read_frame, SWITCH_IO_FLAG_NONE, 0);
if (!SWITCH_READ_ACCEPTABLE(status)) {
break;
switch_core_session_read_lock(vh->session_a);
switch_core_session_read_lock(vh->session_b);
if (!switch_stristr("loopback", source) && !switch_stristr("loopback", b_source)) {
switch_channel_set_flag(channel, CF_VIDEO_PASSIVE);
switch_channel_set_flag(b_channel, CF_VIDEO_PASSIVE);
}
msg.from = __FILE__;
msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ;
switch_core_session_receive_message(vh->session_a, &msg);
switch_core_session_receive_message(vh->session_b, &msg);
while (switch_channel_up_nosig(channel) && switch_channel_up_nosig(b_channel) && vh->up == 1) {
if (switch_channel_media_up(channel)) {
status = switch_core_session_read_video_frame(vh->session_a, &read_frame, SWITCH_IO_FLAG_NONE, 0);
if (!SWITCH_READ_ACCEPTABLE(status)) {
switch_cond_next();
continue;
}
}
if (!switch_test_flag(read_frame, SFF_CNG)) {
if (switch_test_flag(read_frame, SFF_CNG)) {
continue;
}
if (switch_channel_media_up(b_channel)) {
if (switch_core_session_write_video_frame(vh->session_b, read_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
break;
switch_cond_next();
continue;
}
}
}
switch_channel_clear_flag(channel, CF_VIDEO_PASSIVE);
switch_channel_clear_flag(b_channel, CF_VIDEO_PASSIVE);
switch_core_session_kill_channel(vh->session_b, SWITCH_SIG_BREAK);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(vh->session_a), SWITCH_LOG_DEBUG, "%s video thread ended.\n", switch_channel_get_name(channel));
switch_core_session_rwunlock(vh->session_a);
switch_core_session_rwunlock(vh->session_b);
vh->up = 0;
return NULL;
}

File diff suppressed because it is too large Load Diff