Adjust core and add video caps to mod_conference with video follow audio (first cut)

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10314 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2008-11-10 18:26:41 +00:00
parent 44093523f7
commit 49f353b74e
8 changed files with 4312 additions and 4173 deletions

View File

@ -1678,8 +1678,8 @@ SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration);
SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration);
SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string);
SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string);
SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait);
SWITCH_DECLARE(void) switch_cond_yield(uint32_t ms);
///\}

View File

@ -110,6 +110,8 @@ SWITCH_DECLARE(switch_port_t) switch_rtp_set_end_port(switch_port_t port);
*/
SWITCH_DECLARE(switch_port_t) switch_rtp_request_port(const char *ip);
SWITCH_DECLARE(void) switch_rtp_release_port(const char *ip, switch_port_t port);
SWITCH_DECLARE(void) switch_rtp_change_interval(switch_rtp_t *rtp_session, uint32_t ms_per_packet, uint32_t samples_per_interval);
/*!
\brief create a new RTP session handle
\param new_rtp_session a poiter to aim at the new session

File diff suppressed because it is too large Load Diff

View File

@ -686,6 +686,38 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
*frame = NULL;
return SWITCH_STATUS_GENERR;
}
if (tech_pvt->check_frames < 50) {
if (tech_pvt->last_ts && tech_pvt->read_frame.datalen != tech_pvt->read_codec.implementation->encoded_bytes_per_packet) {
switch_size_t codec_ms = (int)(tech_pvt->read_frame.timestamp -
tech_pvt->last_ts) / (tech_pvt->read_codec.implementation->samples_per_second / 1000);
if ((codec_ms % 10) != 0) {
tech_pvt->check_frames = 50;
} else {
if (switch_rtp_ready(tech_pvt->rtp_session) && codec_ms != tech_pvt->codec_ms) {
tech_pvt->codec_ms = codec_ms;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Changing codec ptime to %d\n", tech_pvt->codec_ms);
switch_core_codec_destroy(&tech_pvt->read_codec);
switch_core_codec_destroy(&tech_pvt->write_codec);
if (sofia_glue_tech_set_codec(tech_pvt, 2) != SWITCH_STATUS_SUCCESS) {
*frame = NULL;
return SWITCH_STATUS_GENERR;
}
switch_rtp_change_interval(tech_pvt->rtp_session,
tech_pvt->read_codec.implementation->samples_per_packet,
tech_pvt->codec_ms * 1000);
}
}
tech_pvt->check_frames++;
tech_pvt->last_ts = tech_pvt->read_frame.timestamp;
}
}
if ((bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_packet)) {
frames = (tech_pvt->read_frame.datalen / bytes);
}

View File

@ -505,6 +505,8 @@ struct private_object {
int got_bye;
int hold_laps;
switch_thread_id_t locker;
switch_size_t last_ts;
uint32_t check_frames;
};
struct callback_t {
@ -708,3 +710,4 @@ void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const cha
void sofia_glue_restart_all_profiles(void);
void sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly);
const char * sofia_state_string(int state);
switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force);

View File

@ -182,6 +182,7 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32
} else {
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=silenceSupp:off - - - -\n");
}
if (ptime) {
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=ptime:%d\n", ptime);
}
@ -1576,8 +1577,11 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
tech_pvt->write_codec.agreed_pt = tech_pvt->agreed_pt;
tech_pvt->read_codec.agreed_pt = tech_pvt->agreed_pt;
switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);
if (force != 2) {
switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);
}
tech_pvt->fmtp_out = switch_core_session_strdup(tech_pvt->session, tech_pvt->write_codec.fmtp_out);
if (switch_rtp_ready(tech_pvt->rtp_session)) {

View File

@ -754,6 +754,22 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
return SWITCH_STATUS_SUCCESS;
}
SWITCH_DECLARE(void) switch_rtp_change_interval(switch_rtp_t *rtp_session, uint32_t ms_per_packet, uint32_t samples_per_interval)
{
rtp_session->ms_per_packet = ms_per_packet;
rtp_session->samples_per_interval = rtp_session->conf_samples_per_interval = samples_per_interval;
if (rtp_session->timer_name) {
if (rtp_session->timer.timer_interface) {
switch_core_timer_destroy(&rtp_session->timer);
}
switch_core_timer_init(&rtp_session->timer, rtp_session->timer_name, ms_per_packet / 1000, samples_per_interval, rtp_session->pool);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"RE-Starting timer [%s] %d bytes per %dms\n", rtp_session->timer_name, samples_per_interval, ms_per_packet);
}
}
SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session,
switch_payload_t payload,
uint32_t samples_per_interval,
@ -816,14 +832,14 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session
rtp_session->ms_per_packet = ms_per_packet;
rtp_session->samples_per_interval = rtp_session->conf_samples_per_interval = samples_per_interval;
if (timer_name && !strcasecmp(timer_name, "none")) {
timer_name = NULL;
}
if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER) && switch_strlen_zero(timer_name)) {
timer_name = "soft";
}
if (!switch_strlen_zero(timer_name) && !strcasecmp(timer_name, "none")) {
timer_name = NULL;
}
if (!switch_strlen_zero(timer_name)) {
rtp_session->timer_name = switch_core_strdup(pool, timer_name);
switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
@ -838,6 +854,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session
switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
}
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Not using a timer\n");
switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_NOBLOCK);
}
@ -1260,6 +1277,10 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
while (switch_rtp_ready(rtp_session)) {
int do_cng = 0;
if (rtp_session->timer.interval) {
switch_core_timer_next(&rtp_session->timer);
}
bytes = sizeof(rtp_msg_t);
status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, &bytes);
@ -1268,6 +1289,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
goto end;
}
check = !bytes;
if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_BREAK)) {
switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_BREAK);
do_2833(rtp_session);
@ -1319,12 +1342,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
rtp_session->missed_count = 0;
if (rtp_session->recv_msg.header.pt && (rtp_session->recv_msg.header.pt == rtp_session->cng_pt || rtp_session->recv_msg.header.pt == 13)) {
if (++rtp_session->cng_count == 1) {
return_cng_frame();
}
continue;
} else {
rtp_session->cng_count = 0;
return_cng_frame();
}
}
@ -1333,22 +1351,13 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
}
if (rtp_session->timer.interval) {
check = (uint8_t) (switch_core_timer_check(&rtp_session->timer, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS);
if (bytes) {
switch_core_timer_sync(&rtp_session->timer);
} else {
if (check && switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTO_CNG) &&
rtp_session->timer.samplecount >= (rtp_session->last_write_samplecount + (rtp_session->samples_per_interval * 50))) {
uint8_t data[10] = { 0 };
switch_frame_flag_t frame_flags = SFF_NONE;
data[0] = 65;
rtp_session->cn++;
rtp_common_write(rtp_session, NULL, (void *) data, 2, rtp_session->cng_pt, 0, &frame_flags);
}
}
} else if (bytes) {
check++;
if (check && switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTO_CNG) &&
rtp_session->timer.samplecount >= (rtp_session->last_write_samplecount + (rtp_session->samples_per_interval * 50))) {
uint8_t data[10] = { 0 };
switch_frame_flag_t frame_flags = SFF_NONE;
data[0] = 65;
rtp_session->cn++;
rtp_common_write(rtp_session, NULL, (void *) data, 2, rtp_session->cng_pt, 0, &frame_flags);
}
if (check || bytes) {
@ -1527,8 +1536,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
bytes = jb_frame->dlen + rtp_header_len;
rtp_session->recv_msg.header.ts = htonl(jb_frame->ts);
} else if (!bytes && switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { /* We're late! We're Late! */
if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_NOBLOCK) && status == SWITCH_STATUS_BREAK) {
switch_yield(1000);
continue;
@ -1556,7 +1563,9 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
do_continue:
switch_yield(sleep_mss);
if (!bytes && !rtp_session->timer.interval) {
switch_yield(sleep_mss);
}
}

View File

@ -46,6 +46,7 @@ static switch_memory_pool_t *module_pool = NULL;
static struct {
int32_t RUNNING;
int32_t STARTED;
int32_t use_cond_yield;
switch_mutex_t *mutex;
} globals;
@ -76,6 +77,8 @@ struct timer_matrix {
switch_size_t tick;
uint32_t count;
uint32_t roll;
switch_mutex_t *mutex;
switch_thread_cond_t *cond;
};
typedef struct timer_matrix timer_matrix_t;
@ -103,6 +106,25 @@ static int MONO = 0;
#endif
static void do_yield(switch_interval_time_t t)
{
#if defined(HAVE_CLOCK_NANOSLEEP) && defined(SWITCH_USE_CLOCK_FUNCS)
struct timespec ts;
ts.tv_sec = t / APR_USEC_PER_SEC;
ts.tv_nsec = (t % APR_USEC_PER_SEC) * 1000;
clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL);
#elif defined(HAVE_USLEEP)
usleep(t);
#elif defined(WIN32)
Sleep((DWORD) ((t) / 1000));
#else
apr_sleep(t);
#endif
}
SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable)
{
MONO = enable ? 1 : 0;
@ -139,6 +161,11 @@ SWITCH_DECLARE(void) switch_time_sync(void)
SWITCH_DECLARE(void) switch_sleep(switch_interval_time_t t)
{
if (globals.use_cond_yield == 1) {
switch_cond_yield((t) / 1000);
return;
}
#if defined(HAVE_USLEEP)
usleep(t);
#elif defined(WIN32)
@ -166,13 +193,29 @@ SWITCH_DECLARE(void) switch_sleep(switch_interval_time_t t)
}
SWITCH_DECLARE(void) switch_cond_yield(uint32_t ms)
{
if (!ms) return;
if (globals.use_cond_yield != 1) {
do_yield(ms * 1000);
}
while(globals.RUNNING == 1 && globals.use_cond_yield == 1 && ms--) {
switch_mutex_lock(TIMER_MATRIX[1].mutex);
switch_thread_cond_wait(TIMER_MATRIX[1].cond, TIMER_MATRIX[1].mutex);
switch_mutex_unlock(TIMER_MATRIX[1].mutex);
}
}
static switch_status_t timer_init(switch_timer_t *timer)
{
timer_private_t *private_info;
int sanity = 0;
while (globals.STARTED == 0) {
switch_yield(100000);
do_yield(100000);
if (++sanity == 10) {
break;
}
@ -187,6 +230,10 @@ static switch_status_t timer_init(switch_timer_t *timer)
timeBeginPeriod(1);
#endif
switch_mutex_lock(globals.mutex);
if (!TIMER_MATRIX[timer->interval].mutex) {
switch_mutex_init(&TIMER_MATRIX[timer->interval].mutex, SWITCH_MUTEX_NESTED, module_pool);
switch_thread_cond_create(&TIMER_MATRIX[timer->interval].cond, module_pool);
}
TIMER_MATRIX[timer->interval].count++;
switch_mutex_unlock(globals.mutex);
timer->private_info = private_info;
@ -252,13 +299,21 @@ static switch_status_t timer_sync(switch_timer_t *timer)
static switch_status_t timer_next(switch_timer_t *timer)
{
timer_private_t *private_info = timer->private_info;
timer_step(timer);
#if 1
while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) {
check_roll();
switch_yield(1000);
switch_mutex_lock(TIMER_MATRIX[timer->interval].mutex);
switch_thread_cond_wait(TIMER_MATRIX[timer->interval].cond, TIMER_MATRIX[timer->interval].mutex);
switch_mutex_unlock(TIMER_MATRIX[timer->interval].mutex);
}
#else
while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) {
check_roll();
do_yield(1000);
}
#endif
if (globals.RUNNING == 1) {
return SWITCH_STATUS_SUCCESS;
@ -340,7 +395,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
runtime.initiated = runtime.reference;
break;
}
switch_yield(STEP_MIC);
do_yield(STEP_MIC);
last = ts;
}
}
@ -349,8 +404,15 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
last = 0;
fwd_errs = rev_errs = 0;
switch_mutex_init(&TIMER_MATRIX[1].mutex, SWITCH_MUTEX_NESTED, module_pool);
switch_thread_cond_create(&TIMER_MATRIX[1].cond, module_pool);
globals.use_cond_yield = globals.RUNNING == 1;
while (globals.RUNNING == 1) {
runtime.reference += STEP_MIC;
while ((ts = time_now(runtime.offset)) < runtime.reference) {
if (ts < last) {
if (MONO) {
@ -368,7 +430,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
} else {
rev_errs = 0;
}
switch_yield(STEP_MIC);
do_yield(STEP_MIC);
last = ts;
}
@ -413,11 +475,28 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
tick = 0;
}
TIMER_MATRIX[1].tick++;
if (switch_mutex_trylock(TIMER_MATRIX[1].mutex) == SWITCH_STATUS_SUCCESS) {
switch_thread_cond_broadcast(TIMER_MATRIX[1].cond);
switch_mutex_unlock(TIMER_MATRIX[1].mutex);
}
if (TIMER_MATRIX[1].tick == MAX_TICK) {
TIMER_MATRIX[1].tick = 0;
TIMER_MATRIX[1].roll++;
}
if ((current_ms % MS_PER_TICK) == 0) {
for (x = MS_PER_TICK; x <= MAX_ELEMENTS; x += MS_PER_TICK) {
if ((current_ms % x) == 0) {
if (TIMER_MATRIX[x].count) {
TIMER_MATRIX[x].tick++;
#if 1
if (TIMER_MATRIX[x].mutex && switch_mutex_trylock(TIMER_MATRIX[x].mutex) == SWITCH_STATUS_SUCCESS) {
switch_thread_cond_broadcast(TIMER_MATRIX[x].cond);
switch_mutex_unlock(TIMER_MATRIX[x].mutex);
}
#endif
if (TIMER_MATRIX[x].tick == MAX_TICK) {
TIMER_MATRIX[x].tick = 0;
TIMER_MATRIX[x].roll++;
@ -431,10 +510,22 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
}
}
globals.use_cond_yield = 0;
for (x = MS_PER_TICK; x <= MAX_ELEMENTS; x += MS_PER_TICK) {
if (TIMER_MATRIX[x].mutex && switch_mutex_trylock(TIMER_MATRIX[x].mutex) == SWITCH_STATUS_SUCCESS) {
switch_thread_cond_broadcast(TIMER_MATRIX[x].cond);
switch_mutex_unlock(TIMER_MATRIX[x].mutex);
}
}
switch_mutex_lock(globals.mutex);
globals.RUNNING = 0;
switch_mutex_unlock(globals.mutex);
return SWITCH_STATUS_TERM;
}
@ -641,14 +732,13 @@ SWITCH_MODULE_LOAD_FUNCTION(softtimer_load)
SWITCH_MODULE_SHUTDOWN_FUNCTION(softtimer_shutdown)
{
if (globals.RUNNING) {
if (globals.RUNNING == 1) {
switch_mutex_lock(globals.mutex);
globals.RUNNING = -1;
switch_mutex_unlock(globals.mutex);
while (globals.RUNNING) {
switch_yield(10000);
while (globals.RUNNING == -1) {
do_yield(10000);
}
}
#if defined(WIN32)