FS-7513: add code to track media direction to avoid assigning floor or video layers to those with no signal
This commit is contained in:
parent
4584e6a8e4
commit
628edd1183
|
@ -323,6 +323,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_lock_unlock(switch_core_s
|
||||||
#define switch_core_media_read_unlock(_s, _t) switch_core_media_read_lock_unlock(_s, _t, SWITCH_FALSE)
|
#define switch_core_media_read_unlock(_s, _t) switch_core_media_read_lock_unlock(_s, _t, SWITCH_FALSE)
|
||||||
|
|
||||||
SWITCH_DECLARE(void) switch_core_session_stop_media(switch_core_session_t *session);
|
SWITCH_DECLARE(void) switch_core_session_stop_media(switch_core_session_t *session);
|
||||||
|
SWITCH_DECLARE(switch_media_flow_t) switch_core_session_media_flow(switch_core_session_t *session, switch_media_type_t type);
|
||||||
|
|
||||||
SWITCH_END_EXTERN_C
|
SWITCH_END_EXTERN_C
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2475,6 +2475,13 @@ typedef struct payload_map_s {
|
||||||
|
|
||||||
} payload_map_t;
|
} payload_map_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SWITCH_MEDIA_FLOW_SENDRECV = 0,
|
||||||
|
SWITCH_MEDIA_FLOW_SENDONLY,
|
||||||
|
SWITCH_MEDIA_FLOW_RECVONLY,
|
||||||
|
SWITCH_MEDIA_FLOW_INACTIVE
|
||||||
|
} switch_media_flow_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ICE_GOOGLE_JINGLE = (1 << 0),
|
ICE_GOOGLE_JINGLE = (1 << 0),
|
||||||
ICE_VANILLA = (1 << 1),
|
ICE_VANILLA = (1 << 1),
|
||||||
|
|
|
@ -629,6 +629,7 @@ struct conference_member {
|
||||||
char *video_logo;
|
char *video_logo;
|
||||||
char *video_mute_png;
|
char *video_mute_png;
|
||||||
char *video_reservation_id;
|
char *video_reservation_id;
|
||||||
|
switch_media_flow_t video_flow;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -1271,6 +1272,10 @@ static switch_status_t attach_video_layer(conference_member_t *member, int idx)
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
switch_mutex_lock(member->conference->canvas->mutex);
|
switch_mutex_lock(member->conference->canvas->mutex);
|
||||||
|
|
||||||
layer = &member->conference->canvas->layers[idx];
|
layer = &member->conference->canvas->layers[idx];
|
||||||
|
@ -1677,7 +1682,7 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!layer && conference->canvas->layers_used < conference->canvas->total_layers) {
|
if (!layer && conference->canvas->layers_used < conference->canvas->total_layers && imember->video_flow != SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||||
/* find an empty layer */
|
/* find an empty layer */
|
||||||
for (i = 0; i < conference->canvas->total_layers; i++) {
|
for (i = 0; i < conference->canvas->total_layers; i++) {
|
||||||
mcu_layer_t *xlayer = &conference->canvas->layers[i];
|
mcu_layer_t *xlayer = &conference->canvas->layers[i];
|
||||||
|
@ -3468,6 +3473,10 @@ static void find_video_floor(conference_member_t *member, switch_bool_t entering
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (imember->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!switch_channel_test_flag(imember->channel, CF_VIDEO)) {
|
if (!switch_channel_test_flag(imember->channel, CF_VIDEO)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -3561,6 +3570,7 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe
|
||||||
conference_send_presence(conference);
|
conference_send_presence(conference);
|
||||||
|
|
||||||
channel = switch_core_session_get_channel(member->session);
|
channel = switch_core_session_get_channel(member->session);
|
||||||
|
member->video_flow = switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO);
|
||||||
|
|
||||||
if (switch_channel_test_flag(channel, CF_VIDEO)) {
|
if (switch_channel_test_flag(channel, CF_VIDEO)) {
|
||||||
switch_set_flag_locked(member, MFLAG_ACK_VIDEO);
|
switch_set_flag_locked(member, MFLAG_ACK_VIDEO);
|
||||||
|
@ -3753,7 +3763,6 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe
|
||||||
switch_mutex_unlock(conference->mutex);
|
switch_mutex_unlock(conference->mutex);
|
||||||
status = SWITCH_STATUS_SUCCESS;
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
|
||||||
find_video_floor(member, SWITCH_TRUE);
|
find_video_floor(member, SWITCH_TRUE);
|
||||||
|
|
||||||
|
|
||||||
|
@ -3785,6 +3794,10 @@ static void conference_set_video_floor_holder(conference_obj_t *conference, conf
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (member && member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (conference->video_floor_holder) {
|
if (conference->video_floor_holder) {
|
||||||
if (member && conference->video_floor_holder == member->id) {
|
if (member && conference->video_floor_holder == member->id) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -155,9 +155,9 @@ typedef struct switch_rtp_engine_s {
|
||||||
uint8_t pli;
|
uint8_t pli;
|
||||||
uint8_t nack;
|
uint8_t nack;
|
||||||
uint8_t no_crypto;
|
uint8_t no_crypto;
|
||||||
|
|
||||||
switch_codec_settings_t codec_settings;
|
switch_codec_settings_t codec_settings;
|
||||||
|
switch_media_flow_t rmode;
|
||||||
|
switch_media_flow_t smode;
|
||||||
} switch_rtp_engine_t;
|
} switch_rtp_engine_t;
|
||||||
|
|
||||||
struct switch_media_handle_s {
|
struct switch_media_handle_s {
|
||||||
|
@ -244,6 +244,21 @@ SWITCH_DECLARE(int) switch_core_media_crypto_keylen(switch_rtp_crypto_key_type_t
|
||||||
return SUITES[type].keylen;
|
return SUITES[type].keylen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline switch_media_flow_t sdp_media_flow(unsigned in)
|
||||||
|
{
|
||||||
|
switch(in) {
|
||||||
|
case sdp_sendonly:
|
||||||
|
return SWITCH_MEDIA_FLOW_SENDONLY;
|
||||||
|
case sdp_recvonly:
|
||||||
|
return SWITCH_MEDIA_FLOW_RECVONLY;
|
||||||
|
case sdp_sendrecv:
|
||||||
|
return SWITCH_MEDIA_FLOW_SENDRECV;
|
||||||
|
case sdp_inactive:
|
||||||
|
return SWITCH_MEDIA_FLOW_INACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_MEDIA_FLOW_SENDRECV;
|
||||||
|
}
|
||||||
|
|
||||||
static int get_channels(const char *name, int dft)
|
static int get_channels(const char *name, int dft)
|
||||||
{
|
{
|
||||||
|
@ -1508,6 +1523,13 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t
|
||||||
session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].type = SWITCH_MEDIA_TYPE_VIDEO;
|
session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].type = SWITCH_MEDIA_TYPE_VIDEO;
|
||||||
session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].crypto_type = CRYPTO_INVALID;
|
session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].crypto_type = CRYPTO_INVALID;
|
||||||
|
|
||||||
|
|
||||||
|
switch_channel_set_variable(session->channel, "video_media_flow", "sendrecv");
|
||||||
|
switch_channel_set_variable(session->channel, "audio_media_flow", "sendrecv");
|
||||||
|
|
||||||
|
session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].smode = SWITCH_MEDIA_FLOW_SENDRECV;
|
||||||
|
session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].smode = SWITCH_MEDIA_FLOW_SENDRECV;
|
||||||
|
|
||||||
for (i = 0; i < CRYPTO_INVALID; i++) {
|
for (i = 0; i < CRYPTO_INVALID; i++) {
|
||||||
session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].ssec[i].crypto_type = i;
|
session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].ssec[i].crypto_type = i;
|
||||||
}
|
}
|
||||||
|
@ -1587,6 +1609,30 @@ SWITCH_DECLARE(int32_t) switch_media_handle_test_media_flag(switch_media_handle_
|
||||||
return smh->media_flags[flag];
|
return smh->media_flags[flag];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_media_flow_t) switch_core_session_media_flow(switch_core_session_t *session, switch_media_type_t type)
|
||||||
|
{
|
||||||
|
switch_media_flow_t flow = SWITCH_MEDIA_FLOW_SENDRECV;
|
||||||
|
switch_media_handle_t *smh;
|
||||||
|
switch_rtp_engine_t *engine = NULL;
|
||||||
|
|
||||||
|
switch_assert(session);
|
||||||
|
|
||||||
|
if (!(smh = session->media_handle)) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!smh->media_flags[SCMF_RUNNING]) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
engine = &smh->engines[type];
|
||||||
|
flow = engine->smode;
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
return flow;
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_core_session_media_handle_ready(switch_core_session_t *session)
|
SWITCH_DECLARE(switch_status_t) switch_core_session_media_handle_ready(switch_core_session_t *session)
|
||||||
{
|
{
|
||||||
if (session->media_handle && switch_test_flag(session->media_handle, SMF_INIT)) {
|
if (session->media_handle && switch_test_flag(session->media_handle, SMF_INIT)) {
|
||||||
|
@ -2873,7 +2919,6 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_
|
||||||
engine->ice_in.pwd = switch_core_session_strdup(smh->session, attr->a_value);
|
engine->ice_in.pwd = switch_core_session_strdup(smh->session, attr->a_value);
|
||||||
} else if (!strcasecmp(attr->a_name, "ice-options")) {
|
} else if (!strcasecmp(attr->a_name, "ice-options")) {
|
||||||
engine->ice_in.options = switch_core_session_strdup(smh->session, attr->a_value);
|
engine->ice_in.options = switch_core_session_strdup(smh->session, attr->a_value);
|
||||||
|
|
||||||
} else if (switch_rtp_has_dtls() && dtls_ok(smh->session) && !strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)) {
|
} else if (switch_rtp_has_dtls() && dtls_ok(smh->session) && !strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)) {
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
|
@ -3552,6 +3597,25 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||||
sendonly = 1;
|
sendonly = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
a_engine->rmode = sdp_media_flow(m->m_mode);
|
||||||
|
|
||||||
|
if (sdp_type == SDP_TYPE_REQUEST) {
|
||||||
|
switch(a_engine->rmode) {
|
||||||
|
case SWITCH_MEDIA_FLOW_RECVONLY:
|
||||||
|
switch_channel_set_variable(smh->session->channel, "audio_media_flow", "sendonly");
|
||||||
|
a_engine->smode = SWITCH_MEDIA_FLOW_SENDONLY;
|
||||||
|
break;
|
||||||
|
case SWITCH_MEDIA_FLOW_SENDONLY:
|
||||||
|
switch_channel_set_variable(smh->session->channel, "audio_media_flow", "recvonly");
|
||||||
|
a_engine->smode = SWITCH_MEDIA_FLOW_RECVONLY;
|
||||||
|
default:
|
||||||
|
switch_channel_set_variable(smh->session->channel, "audio_media_flow", "sendrecv");
|
||||||
|
a_engine->smode = SWITCH_MEDIA_FLOW_SENDRECV;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) {
|
for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) {
|
||||||
if (zstr(attr->a_name)) {
|
if (zstr(attr->a_name)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -3596,6 +3660,13 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||||
switch_channel_set_variable(session->channel, "media_audio_mode", NULL);
|
switch_channel_set_variable(session->channel, "media_audio_mode", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sendonly) {
|
||||||
|
a_engine->smode = sdp_sendonly;
|
||||||
|
} else if (recvonly) {
|
||||||
|
a_engine->smode = sdp_recvonly;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!(switch_media_handle_test_media_flag(smh, SCMF_DISABLE_HOLD)
|
if (!(switch_media_handle_test_media_flag(smh, SCMF_DISABLE_HOLD)
|
||||||
|| ((val = switch_channel_get_variable(session->channel, "rtp_disable_hold"))
|
|| ((val = switch_channel_get_variable(session->channel, "rtp_disable_hold"))
|
||||||
&& switch_true(val)))
|
&& switch_true(val)))
|
||||||
|
@ -4116,6 +4187,26 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v_engine->rmode = sdp_media_flow(m->m_mode);
|
||||||
|
|
||||||
|
if (sdp_type == SDP_TYPE_REQUEST) {
|
||||||
|
switch(v_engine->rmode) {
|
||||||
|
case SWITCH_MEDIA_FLOW_RECVONLY:
|
||||||
|
switch_channel_set_variable(smh->session->channel, "video_media_flow", "sendonly");
|
||||||
|
v_engine->smode = SWITCH_MEDIA_FLOW_SENDONLY;
|
||||||
|
break;
|
||||||
|
case SWITCH_MEDIA_FLOW_SENDONLY:
|
||||||
|
switch_channel_set_variable(smh->session->channel, "video_media_flow", "recvonly");
|
||||||
|
v_engine->smode = SWITCH_MEDIA_FLOW_RECVONLY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
switch_channel_set_variable(smh->session->channel, "video_media_flow", "sendrecv");
|
||||||
|
v_engine->smode = SWITCH_MEDIA_FLOW_SENDRECV;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (map = m->m_rtpmaps; map; map = map->rm_next) {
|
for (map = m->m_rtpmaps; map; map = map->rm_next) {
|
||||||
|
|
||||||
if (switch_rtp_has_dtls() && dtls_ok(session)) {
|
if (switch_rtp_has_dtls() && dtls_ok(session)) {
|
||||||
|
@ -4484,7 +4575,7 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
|
||||||
switch_status_t status;
|
switch_status_t status;
|
||||||
switch_frame_t *read_frame;
|
switch_frame_t *read_frame;
|
||||||
switch_media_handle_t *smh;
|
switch_media_handle_t *smh;
|
||||||
uint32_t loops = 0;
|
uint32_t loops = 0, xloops = 0;
|
||||||
|
|
||||||
if (!(smh = session->media_handle)) {
|
if (!(smh = session->media_handle)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -4500,13 +4591,21 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
|
||||||
switch_core_session_request_video_refresh(session);
|
switch_core_session_request_video_refresh(session);
|
||||||
|
|
||||||
while (switch_channel_up_nosig(channel)) {
|
while (switch_channel_up_nosig(channel)) {
|
||||||
|
int do_sleep = 0;
|
||||||
|
|
||||||
if (!switch_channel_test_flag(channel, CF_VIDEO)) {
|
if (!switch_channel_test_flag(channel, CF_VIDEO)) {
|
||||||
if ((++loops % 100) == 0) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Waiting for video......\n");
|
if ((++loops % 100) == 0) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Waiting for video......\n");
|
||||||
switch_yield(20000);
|
switch_yield(20000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switch_channel_test_flag(channel, CF_VIDEO_PASSIVE)) {
|
if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||||
|
do_sleep = (++xloops > 20);
|
||||||
|
} else {
|
||||||
|
xloops = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_channel_test_flag(channel, CF_VIDEO_PASSIVE) || do_sleep) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread paused. Echo is %s\n",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread paused. Echo is %s\n",
|
||||||
switch_channel_get_name(session->channel), switch_channel_test_flag(channel, CF_VIDEO_ECHO) ? "on" : "off");
|
switch_channel_get_name(session->channel), switch_channel_test_flag(channel, CF_VIDEO_ECHO) ? "on" : "off");
|
||||||
switch_thread_cond_wait(mh->cond, mh->cond_mutex);
|
switch_thread_cond_wait(mh->cond, mh->cond_mutex);
|
||||||
|
@ -4515,7 +4614,7 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
|
||||||
switch_core_session_request_video_refresh(session);
|
switch_core_session_request_video_refresh(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switch_channel_test_flag(channel, CF_VIDEO_PASSIVE)) {
|
if (switch_channel_test_flag(channel, CF_VIDEO_PASSIVE) || do_sleep) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6714,11 +6813,19 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if (zstr(sr)) {
|
if (zstr(sr)) {
|
||||||
if ((var_val = switch_channel_get_variable(session->channel, "media_audio_mode"))) {
|
if (a_engine->smode == SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||||
sr = var_val;
|
sr = "sendonly";
|
||||||
|
} else if (a_engine->smode == SWITCH_MEDIA_FLOW_RECVONLY) {
|
||||||
|
sr = "recvonly";
|
||||||
} else {
|
} else {
|
||||||
sr = "sendrecv";
|
sr = "sendrecv";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if ((var_val = switch_channel_get_variable(session->channel, "media_audio_mode"))) {
|
||||||
|
// sr = var_val;
|
||||||
|
//} else {
|
||||||
|
// sr = "sendrecv";
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!smh->owner_id) {
|
if (!smh->owner_id) {
|
||||||
|
@ -7186,6 +7293,12 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
|
||||||
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s%s", append_video, end_of(append_video) == '\n' ? "" : "\n");
|
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s%s", append_video, end_of(append_video) == '\n' ? "" : "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (v_engine->smode == SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||||
|
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=sendonly\n");
|
||||||
|
} else if (v_engine->smode == SWITCH_MEDIA_FLOW_RECVONLY) {
|
||||||
|
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=recvonly\n");
|
||||||
|
}
|
||||||
|
|
||||||
} else if (smh->mparams->num_codecs) {
|
} else if (smh->mparams->num_codecs) {
|
||||||
int i;
|
int i;
|
||||||
int already_did[128] = { 0 };
|
int already_did[128] = { 0 };
|
||||||
|
|
Loading…
Reference in New Issue