char *video_logo;
char *video_mute_png;
char *video_reservation_id;
+ switch_media_flow_t video_flow;
};
typedef enum {
return SWITCH_STATUS_FALSE;
}
+ if (member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) {
+ return SWITCH_STATUS_FALSE;
+ }
+
switch_mutex_lock(member->conference->canvas->mutex);
layer = &member->conference->canvas->layers[idx];
}
}
- 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 */
for (i = 0; i < conference->canvas->total_layers; i++) {
mcu_layer_t *xlayer = &conference->canvas->layers[i];
continue;
}
+ if (imember->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) {
+ continue;
+ }
+
if (!switch_channel_test_flag(imember->channel, CF_VIDEO)) {
continue;
}
conference_send_presence(conference);
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)) {
switch_set_flag_locked(member, MFLAG_ACK_VIDEO);
switch_mutex_unlock(conference->mutex);
status = SWITCH_STATUS_SUCCESS;
-
find_video_floor(member, SWITCH_TRUE);
return;
}
+ if (member && member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) {
+ return;
+ }
+
if (conference->video_floor_holder) {
if (member && conference->video_floor_holder == member->id) {
return;
uint8_t pli;
uint8_t nack;
uint8_t no_crypto;
-
switch_codec_settings_t codec_settings;
-
+ switch_media_flow_t rmode;
+ switch_media_flow_t smode;
} switch_rtp_engine_t;
struct switch_media_handle_s {
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)
{
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;
+
+ 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++) {
session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].ssec[i].crypto_type = i;
}
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)
{
if (session->media_handle && switch_test_flag(session->media_handle, SMF_INIT)) {
engine->ice_in.pwd = switch_core_session_strdup(smh->session, attr->a_value);
} else if (!strcasecmp(attr->a_name, "ice-options")) {
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)) {
char *p;
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) {
if (zstr(attr->a_name)) {
continue;
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)
|| ((val = switch_channel_get_variable(session->channel, "rtp_disable_hold"))
&& switch_true(val)))
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) {
if (switch_rtp_has_dtls() && dtls_ok(session)) {
switch_status_t status;
switch_frame_t *read_frame;
switch_media_handle_t *smh;
- uint32_t loops = 0;
+ uint32_t loops = 0, xloops = 0;
if (!(smh = session->media_handle)) {
return NULL;
switch_core_session_request_video_refresh(session);
while (switch_channel_up_nosig(channel)) {
+ int do_sleep = 0;
+
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");
switch_yield(20000);
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_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_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;
}
//}
if (zstr(sr)) {
- if ((var_val = switch_channel_get_variable(session->channel, "media_audio_mode"))) {
- sr = var_val;
+ if (a_engine->smode == SWITCH_MEDIA_FLOW_SENDONLY) {
+ sr = "sendonly";
+ } else if (a_engine->smode == SWITCH_MEDIA_FLOW_RECVONLY) {
+ sr = "recvonly";
} else {
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 (append_video) {
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) {
int i;