in chime/chime-call-audio.c [139:225]
static void do_send_rt_packet(ChimeCallAudio *audio, GstBuffer *buffer)
{
GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
guint nr_samples; /* This is added *after* sending the frame */
g_mutex_lock(&audio->rt_lock);
gint64 now = g_get_monotonic_time();
if (!audio->timeout_source && audio->last_rx + 10000000 < now) {
chime_debug("RX timeout, reconnect audio\n");
audio->timeout_source = g_timeout_add(0, audio_reconnect, audio);
}
if (buffer && GST_BUFFER_DURATION_IS_VALID(buffer) &&
GST_BUFFER_DTS_IS_VALID(buffer) && gst_rtp_buffer_map(buffer, GST_MAP_READ, &rtp)) {
GstClockTime dts, pts, dur;
dts = GST_BUFFER_DTS(buffer);
pts = GST_BUFFER_PTS(buffer);
dur = GST_BUFFER_DURATION(buffer);
nr_samples = GST_BUFFER_DURATION(buffer) / NS_PER_SAMPLE;
chime_debug("buf dts %ld pts %ld dur %ld samples %d\n", dts, pts, dur, nr_samples);
if (audio->next_dts) {
int frames_missed;
if (dts < audio->next_dts) {
chime_debug("Out of order frame %ld < %ld\n", dts, audio->next_dts);
goto drop;
}
frames_missed = (dts - audio->next_dts) / dur;
if (frames_missed) {
chime_debug("Missed %d frames\n", frames_missed);
audio->audio_msg.sample_time += frames_missed * nr_samples;
audio->next_dts += frames_missed * dur;
}
audio->next_dts += dur;
} else {
audio->next_dts = dts + dur;
}
if (audio->state == CHIME_AUDIO_STATE_AUDIO) {
// printf ("State %d, send audio\n", audio->state);
audio->audio_msg.audio.len = gst_rtp_buffer_get_payload_len(&rtp);
audio->audio_msg.audio.data = gst_rtp_buffer_get_payload(&rtp);
} else {
// printf ("State %d, send no audio\n", audio->state);
audio->audio_msg.audio.len = 0;
}
} else {
int delta_samples = (now - audio->last_send_local_time) / NS_PER_SAMPLE;
if (delta_samples > 480)
audio->audio_msg.sample_time += delta_samples - 320;
audio->next_dts = 0;
nr_samples = 320;
audio->audio_msg.audio.len = 0;
}
audio->audio_msg.seq = (audio->audio_msg.seq + 1) & 0xffff;
if (audio->last_server_time_offset) {
gint64 t = audio->last_server_time_offset + now;
if (audio->echo_server_time) {
audio->audio_msg.has_echo_time = 1;
audio->audio_msg.echo_time = t;
audio->echo_server_time = FALSE;
}
audio->audio_msg.has_server_time = TRUE;
audio->audio_msg.server_time = t;
} else
audio->audio_msg.has_echo_time = 0;
audio->audio_msg.has_total_frames_lost = TRUE;
audio->audio_msg.total_frames_lost = 0;
audio->audio_msg.has_ntp_time = TRUE;
audio->audio_msg.ntp_time = g_get_real_time();
audio->audio_msg.has_audio = TRUE;
audio->last_send_local_time = now;
chime_call_transport_send_packet(audio, XRP_RT_MESSAGE, &audio->rt_msg.base);
if (audio->audio_msg.audio.data) {
audio->audio_msg.audio.data = NULL;
gst_rtp_buffer_unmap(&rtp);
}
audio->audio_msg.sample_time += nr_samples;
drop:
g_mutex_unlock(&audio->rt_lock);
}