add mutex in media_engine to prevent double read in video thread

This commit is contained in:
Anthony Minessale 2013-08-16 20:34:29 +05:00
parent d4d2d988a3
commit 80e2633bb7
1 changed files with 26 additions and 7 deletions

View File

@ -156,6 +156,7 @@ typedef struct switch_rtp_engine_s {
struct media_helper mh;
switch_thread_t *media_thread;
switch_mutex_t *read_mutex;
} switch_rtp_engine_t;
@ -1224,6 +1225,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
switch_assert(engine->rtp_session != NULL);
engine->read_frame.datalen = 0;
if (switch_mutex_trylock(engine->read_mutex) != SWITCH_STATUS_SUCCESS) {
/* return CNG for now */
*frame = &engine->read_frame;
switch_set_flag((*frame), SFF_CNG);
(*frame)->datalen = engine->read_impl.encoded_bytes_per_packet;
memset((*frame)->data, 0, (*frame)->datalen);
return SWITCH_STATUS_SUCCESS;
}
while (smh->media_flags[SCMF_RUNNING] && engine->read_frame.datalen == 0) {
engine->read_frame.flags = SFF_NONE;
@ -1239,13 +1249,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
(*frame)->datalen = engine->read_impl.encoded_bytes_per_packet;
memset((*frame)->data, 0, (*frame)->datalen);
switch_channel_execute_on(session->channel, "execute_on_media_timeout");
return SWITCH_STATUS_SUCCESS;
switch_goto_status(SWITCH_STATUS_SUCCESS, end);
}
switch_channel_hangup(session->channel, SWITCH_CAUSE_MEDIA_TIMEOUT);
}
return status;
goto end;
}
/* Try to read an RTCP frame, if successful raise an event */
@ -1322,7 +1332,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
/* Fast PASS! */
if (switch_test_flag((&engine->read_frame), SFF_PROXY_PACKET)) {
*frame = &engine->read_frame;
return SWITCH_STATUS_SUCCESS;
switch_goto_status(SWITCH_STATUS_SUCCESS, end);
}
if (switch_rtp_has_dtmf(engine->rtp_session)) {
@ -1338,7 +1348,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
if (!switch_test_flag((&engine->read_frame), SFF_CNG)) {
if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) {
*frame = NULL;
return SWITCH_STATUS_GENERR;
switch_goto_status(SWITCH_STATUS_GENERR, end);
}
/* check for timing or codec issues */
@ -1475,7 +1485,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
if (switch_rtp_ready(engine->rtp_session)) {
if (switch_core_media_set_codec(session, 2, 0) != SWITCH_STATUS_SUCCESS) {
*frame = NULL;
return SWITCH_STATUS_GENERR;
switch_goto_status(SWITCH_STATUS_GENERR, end);
}
if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec"))) {
@ -1516,7 +1526,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
switch_set_flag((*frame), SFF_CNG);
(*frame)->datalen = engine->read_impl.encoded_bytes_per_packet;
memset((*frame)->data, 0, (*frame)->datalen);
return SWITCH_STATUS_SUCCESS;
switch_goto_status(SWITCH_STATUS_SUCCESS, end);
}
}
@ -1541,7 +1551,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
*frame = &engine->read_frame;
return SWITCH_STATUS_SUCCESS;
status = SWITCH_STATUS_SUCCESS;
end:
switch_mutex_unlock(engine->read_mutex);
return status;
}
//?
@ -4164,6 +4180,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
uint8_t inb = switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND;
const char *ssrc;
switch_mutex_init(&a_engine->read_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
//switch_core_media_set_rtp_session(session, SWITCH_MEDIA_TYPE_AUDIO, a_engine->rtp_session);
if ((ssrc = switch_channel_get_variable(session->channel, "rtp_use_ssrc"))) {
@ -4623,6 +4641,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
switch_thread_cond_create(&v_engine->mh.cond, pool);
switch_mutex_init(&v_engine->mh.cond_mutex, SWITCH_MUTEX_NESTED, pool);
switch_mutex_init(&v_engine->read_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));
}