]> www.infradead.org Git - pidgin-chime.git/commitdiff
Attempt to drop only whole frames, not arbitary gaps.
authorDavid Woodhouse <dwmw@amazon.co.uk>
Tue, 7 May 2019 15:40:17 +0000 (16:40 +0100)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Tue, 7 May 2019 15:40:17 +0000 (16:40 +0100)
Perhaps this stops the strange effects we get when we lose outbound
audio frames on a busy system and something goes out of sync.

chime/chime-call-audio.c

index ff463abc84aea5fc4900653fd2d3c61658d4cd20..52c7469cdfb9be25f0de2464ae591b2bcbfc140e 100644 (file)
@@ -147,28 +147,6 @@ static void do_send_rt_packet(ChimeCallAudio *audio, GstBuffer *buffer)
                chime_debug("RX timeout, reconnect audio\n");
                audio->timeout_source = g_timeout_add(0, audio_reconnect, audio);
        }
-       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;
-
        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;
@@ -179,12 +157,24 @@ static void do_send_rt_packet(ChimeCallAudio *audio, GstBuffer *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 (audio->next_dts && dts > audio->next_dts) {
-                       /* We skipped some. */
-                       audio->audio_msg.sample_time += (dts - audio->next_dts) / NS_PER_SAMPLE;
+                       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;
                }
-               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);
@@ -201,6 +191,28 @@ static void do_send_rt_packet(ChimeCallAudio *audio, GstBuffer *buffer)
                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) {
@@ -208,6 +220,7 @@ static void do_send_rt_packet(ChimeCallAudio *audio, GstBuffer *buffer)
                gst_rtp_buffer_unmap(&rtp);
        }
        audio->audio_msg.sample_time += nr_samples;
+ drop:
        g_mutex_unlock(&audio->rt_lock);
 }