(uint32_t) bytes, (uint32_t) (*frame)->datalen);
switch_buffer_create_dynamic(&session->raw_read_buffer, bytes * SWITCH_BUFFER_BLOCK_FRAMES, bytes * SWITCH_BUFFER_START_FRAMES, 0);
}
+
if (!switch_buffer_write(session->raw_read_buffer, read_frame->data, read_frame->datalen)) {
status = SWITCH_STATUS_MEMERR;
goto done;
status = perform_write(session, write_frame, flags, stream_id);
goto error;
} else {
- switch_size_t used;
- uint32_t bytes;
- switch_size_t frames;
-
if (!session->raw_write_buffer) {
switch_size_t bytes_per_packet = session->write_impl.decoded_bytes_per_packet;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
status = SWITCH_STATUS_MEMERR; goto error;
}
- used = switch_buffer_inuse(session->raw_write_buffer);
- bytes = session->write_impl.decoded_bytes_per_packet;
- frames = (used / bytes);
-
status = SWITCH_STATUS_SUCCESS;
- if (!frames) {
- goto error;
- } else {
- switch_size_t x;
- for (x = 0; x < frames; x++) {
- if (switch_channel_down(session->channel) || !session->raw_write_buffer) {
- goto error;
- }
- if ((session->raw_write_frame.datalen = (uint32_t)
- switch_buffer_read(session->raw_write_buffer, session->raw_write_frame.data, bytes)) != 0) {
- int rate;
- enc_frame = &session->raw_write_frame;
- session->raw_write_frame.rate = session->write_impl.actual_samples_per_second;
- session->enc_write_frame.datalen = session->enc_write_frame.buflen;
- session->enc_write_frame.timestamp = 0;
-
-
- if (frame->codec && frame->codec->implementation && switch_core_codec_ready(frame->codec)) {
- rate = frame->codec->implementation->actual_samples_per_second;
- } else {
- rate = session->write_impl.actual_samples_per_second;
- }
-
- status = switch_core_codec_encode(session->write_codec,
- frame->codec,
- enc_frame->data,
- enc_frame->datalen,
- rate,
- session->enc_write_frame.data,
- &session->enc_write_frame.datalen,
- &session->enc_write_frame.rate, &flag);
+ while(switch_buffer_inuse(session->raw_write_buffer) >= session->write_impl.decoded_bytes_per_packet) {
+ int rate;
+
+ if (switch_channel_down(session->channel) || !session->raw_write_buffer) {
+ goto error;
+ }
+ if ((session->raw_write_frame.datalen = (uint32_t)
+ switch_buffer_read(session->raw_write_buffer, session->raw_write_frame.data, session->write_impl.decoded_bytes_per_packet)) == 0) {
+ goto error;
+ }
+
+ enc_frame = &session->raw_write_frame;
+ session->raw_write_frame.rate = session->write_impl.actual_samples_per_second;
+ session->enc_write_frame.datalen = session->enc_write_frame.buflen;
+ session->enc_write_frame.timestamp = 0;
+
+
+ if (frame->codec && frame->codec->implementation && switch_core_codec_ready(frame->codec)) {
+ rate = frame->codec->implementation->actual_samples_per_second;
+ } else {
+ rate = session->write_impl.actual_samples_per_second;
+ }
-
+ status = switch_core_codec_encode(session->write_codec,
+ frame->codec,
+ enc_frame->data,
+ enc_frame->datalen,
+ rate,
+ session->enc_write_frame.data,
+ &session->enc_write_frame.datalen,
+ &session->enc_write_frame.rate, &flag);
- switch (status) {
- case SWITCH_STATUS_RESAMPLE:
- resample++;
- session->enc_write_frame.codec = session->write_codec;
- session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
- session->enc_write_frame.m = frame->m;
- session->enc_write_frame.ssrc = frame->ssrc;
- session->enc_write_frame.payload = session->write_impl.ianacode;
- write_frame = &session->enc_write_frame;
- if (!session->write_resampler) {
- switch_mutex_lock(session->resample_mutex);
- if (!session->write_resampler) {
- status = switch_resample_create(&session->write_resampler,
- frame->codec->implementation->actual_samples_per_second,
- session->write_impl.actual_samples_per_second,
- session->write_impl.decoded_bytes_per_packet,
- SWITCH_RESAMPLE_QUALITY, 1);
- }
- switch_mutex_unlock(session->resample_mutex);
+
+ switch (status) {
+ case SWITCH_STATUS_RESAMPLE:
+ resample++;
+ session->enc_write_frame.codec = session->write_codec;
+ session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
+ session->enc_write_frame.m = frame->m;
+ session->enc_write_frame.ssrc = frame->ssrc;
+ session->enc_write_frame.payload = session->write_impl.ianacode;
+ write_frame = &session->enc_write_frame;
+ if (!session->write_resampler) {
+ switch_mutex_lock(session->resample_mutex);
+ if (!session->write_resampler) {
+ status = switch_resample_create(&session->write_resampler,
+ frame->codec->implementation->actual_samples_per_second,
+ session->write_impl.actual_samples_per_second,
+ session->write_impl.decoded_bytes_per_packet,
+ SWITCH_RESAMPLE_QUALITY, 1);
+ }
+ switch_mutex_unlock(session->resample_mutex);
- if (status != SWITCH_STATUS_SUCCESS) {
- goto done;
- }
- }
- break;
- case SWITCH_STATUS_SUCCESS:
- session->enc_write_frame.codec = session->write_codec;
- session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
- session->enc_write_frame.m = frame->m;
- session->enc_write_frame.ssrc = frame->ssrc;
- session->enc_write_frame.payload = session->write_impl.ianacode;
- write_frame = &session->enc_write_frame;
- break;
- case SWITCH_STATUS_NOOP:
- if (session->write_resampler) {
- switch_mutex_lock(session->resample_mutex);
- if (session->write_resampler) {
- switch_resample_destroy(&session->write_resampler);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
- }
- switch_mutex_unlock(session->resample_mutex);
- }
- enc_frame->codec = session->write_codec;
- enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
- enc_frame->m = frame->m;
- enc_frame->ssrc = frame->ssrc;
- enc_frame->payload = enc_frame->codec->implementation->ianacode;
- write_frame = enc_frame;
- status = SWITCH_STATUS_SUCCESS;
- break;
- case SWITCH_STATUS_NOT_INITALIZED:
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
- write_frame = NULL;
- goto error;
- default:
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error %d!\n",
- session->read_codec->codec_interface->interface_name, status);
- write_frame = NULL;
- goto error;
+ if (status != SWITCH_STATUS_SUCCESS) {
+ goto done;
+ }
+ }
+ break;
+ case SWITCH_STATUS_SUCCESS:
+ session->enc_write_frame.codec = session->write_codec;
+ session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t);
+ session->enc_write_frame.m = frame->m;
+ session->enc_write_frame.ssrc = frame->ssrc;
+ session->enc_write_frame.payload = session->write_impl.ianacode;
+ write_frame = &session->enc_write_frame;
+ break;
+ case SWITCH_STATUS_NOOP:
+ if (session->write_resampler) {
+ switch_mutex_lock(session->resample_mutex);
+ if (session->write_resampler) {
+ switch_resample_destroy(&session->write_resampler);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
}
+ switch_mutex_unlock(session->resample_mutex);
+ }
+ enc_frame->codec = session->write_codec;
+ enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
+ enc_frame->m = frame->m;
+ enc_frame->ssrc = frame->ssrc;
+ enc_frame->payload = enc_frame->codec->implementation->ianacode;
+ write_frame = enc_frame;
+ status = SWITCH_STATUS_SUCCESS;
+ break;
+ case SWITCH_STATUS_NOT_INITALIZED:
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec init error!\n");
+ write_frame = NULL;
+ goto error;
+ default:
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s encoder error %d!\n",
+ session->read_codec->codec_interface->interface_name, status);
+ write_frame = NULL;
+ goto error;
+ }
- if (!did_write_resample && session->read_resampler) {
- short *data = write_frame->data;
- switch_mutex_lock(session->resample_mutex);
- if (session->read_resampler) {
- switch_resample_process(session->read_resampler, data, write_frame->datalen / 2);
- memcpy(data, session->read_resampler->to, session->read_resampler->to_len * 2);
- write_frame->samples = session->read_resampler->to_len;
- write_frame->datalen = session->read_resampler->to_len * 2;
- write_frame->rate = session->read_resampler->to_rate;
- }
- switch_mutex_unlock(session->resample_mutex);
+ if (!did_write_resample && session->read_resampler) {
+ short *data = write_frame->data;
+ switch_mutex_lock(session->resample_mutex);
+ if (session->read_resampler) {
+ switch_resample_process(session->read_resampler, data, write_frame->datalen / 2);
+ memcpy(data, session->read_resampler->to, session->read_resampler->to_len * 2);
+ write_frame->samples = session->read_resampler->to_len;
+ write_frame->datalen = session->read_resampler->to_len * 2;
+ write_frame->rate = session->read_resampler->to_rate;
+ }
+ switch_mutex_unlock(session->resample_mutex);
- }
+ }
- if (flag & SFF_CNG) {
- switch_set_flag(write_frame, SFF_CNG);
- }
+ if (flag & SFF_CNG) {
+ switch_set_flag(write_frame, SFF_CNG);
+ }
- if (ptime_mismatch || resample) {
- write_frame->timestamp = 0;
- }
+ if (ptime_mismatch || resample) {
+ write_frame->timestamp = 0;
+ }
- if ((status = perform_write(session, write_frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
- break;
- }
- }
+ if ((status = perform_write(session, write_frame, flags, stream_id)) != SWITCH_STATUS_SUCCESS) {
+ break;
}
- goto error;
+
}
+
+ goto error;
}
}
+
+
+
+
done:
}
if (do_write) {
-
-
-
- status = perform_write(session, write_frame, flags, stream_id);
-
-
+ status = perform_write(session, write_frame, flags, stream_id);
}
error:
char *remote_host_str;
switch_time_t last_stun;
uint32_t samples_per_interval;
+ uint32_t samples_per_second;
uint32_t conf_samples_per_interval;
uint32_t rsamples_per_interval;
uint32_t ms_per_packet;
switch_rtp_bug_flag_t rtp_bugs;
switch_rtp_stats_t stats;
int hot_hits;
+ int sync_packets;
#ifdef ENABLE_ZRTP
zrtp_session_t *zrtp_session;
return SWITCH_STATUS_SUCCESS;
}
-SWITCH_DECLARE(switch_status_t) switch_rtp_change_interval(switch_rtp_t *rtp_session, uint32_t ms_per_packet, uint32_t samples_per_interval)
+SWITCH_DECLARE(switch_status_t) switch_rtp_set_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;
rtp_session->missed_count = 0;
+ rtp_session->samples_per_second = (uint32_t)((double)(1000.0f / (double)(rtp_session->ms_per_packet / 1000)) * (double)rtp_session->samples_per_interval);
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_rtp_change_interval(switch_rtp_t *rtp_session, uint32_t ms_per_packet, uint32_t samples_per_interval)
+{
+ switch_rtp_set_interval(rtp_session, ms_per_packet, samples_per_interval);
+
if (rtp_session->timer_name) {
if (rtp_session->timer.timer_interface) {
switch_core_timer_destroy(&rtp_session->timer);
rtp_session->recv_msg.header.cc = 0;
rtp_session->payload = payload;
- rtp_session->ms_per_packet = ms_per_packet;
- rtp_session->samples_per_interval = rtp_session->conf_samples_per_interval = samples_per_interval;
+
+ switch_rtp_set_interval(rtp_session, ms_per_packet, samples_per_interval);
+ rtp_session->conf_samples_per_interval = samples_per_interval;
if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER) && switch_strlen_zero(timer_name)) {
timer_name = "soft";
return rtp_session->sock_input;
}
-SWITCH_DECLARE(void) switch_rtp_set_default_samples_per_interval(switch_rtp_t *rtp_session, uint32_t samples_per_interval)
-{
- rtp_session->samples_per_interval = samples_per_interval;
-}
-
SWITCH_DECLARE(uint32_t) switch_rtp_get_default_samples_per_interval(switch_rtp_t *rtp_session)
{
return rtp_session->samples_per_interval;
if ((switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTOFLUSH) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_STICKY_FLUSH)) &&
rtp_session->read_pollfd) {
if (switch_poll(rtp_session->read_pollfd, 1, &fdr, 1) == SWITCH_STATUS_SUCCESS) {
- if (++rtp_session->hot_hits >= 10) {
+ rtp_session->hot_hits += rtp_session->samples_per_interval;
+
+ if (rtp_session->hot_hits >= rtp_session->samples_per_second * 60) {
hot_socket = 1;
}
} else {
}
if (hot_socket) {
+ rtp_session->sync_packets++;
switch_core_timer_sync(&rtp_session->timer);
} else {
+ if (rtp_session->sync_packets) {
+#if 0
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
+ "Auto-Flush catching up %d packets (%d)ms.\n",
+ rtp_session->sync_packets, rtp_session->ms_per_packet * rtp_session->sync_packets);
+#endif
+ rtp_session->sync_packets = 0;
+ }
switch_core_timer_next(&rtp_session->timer);
}
}
rtp_session->ts = (uint32_t) timestamp;
} else if (rtp_session->timer.timer_interface) {
rtp_session->ts = rtp_session->timer.samplecount;
+
if (rtp_session->ts <= rtp_session->last_write_ts) {
rtp_session->ts = rtp_session->last_write_ts + rtp_session->samples_per_interval;
}