]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
account for lost frames during ptime detection
authorHristo Trendev <htrendev@gmail.com>
Thu, 9 Oct 2014 09:37:52 +0000 (11:37 +0200)
committerHristo Trendev <htrendev@gmail.com>
Thu, 9 Oct 2014 09:37:52 +0000 (11:37 +0200)
This allows the "broken ptime" detection to work correctly when packet
loss is present on the wire. In addition to the timestamps this patch
adds frame sequence tracking and corrects the timestamp difference
only as needed and according to the number of lost packets.

FS-6898 #resolve

src/switch_core_media.c

index 73d404cfa906ba363a2a7c888d1a242129fee87f..0bb16692151fe3a5d488fc55c5f4d7e36c090eff 100644 (file)
@@ -95,6 +95,7 @@ typedef struct switch_rtp_engine_s {
        switch_codec_implementation_t write_impl;
 
        switch_size_t last_ts;
+       switch_size_t last_seq;
        uint32_t check_frames;
        uint32_t mismatch_count;
        uint32_t last_codec_ms;
@@ -1743,6 +1744,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
                        
                        engine->check_frames = 0;
                        engine->last_ts = 0;
+                       engine->last_seq = 0;
 
                        do_cng = 1;
                }
@@ -1869,8 +1871,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
                                                        uint32_t codec_ms = (int) (engine->read_frame.timestamp -
                                                                                                           engine->last_ts) / (engine->read_impl.samples_per_second / 1000);
 
+                                                       if (engine->last_seq && (int) (engine->read_frame.seq - engine->last_seq) > 1) {
+                                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Correcting calculated ptime value from %d to %d to compensate for %d lost packet(s)\n", codec_ms, codec_ms / (int) (engine->read_frame.seq - engine->last_seq), (int) (engine->read_frame.seq - engine->last_seq - 1));
+                                                               codec_ms = codec_ms / (int) (engine->read_frame.seq - engine->last_seq);
+                                                       }
+
                                                        if ((codec_ms % 10) != 0 || codec_ms > engine->read_impl.samples_per_packet * 10) {
                                                                engine->last_ts = 0;
+                                                               engine->last_seq = 0;
                                                                goto skip;
                                                        }
 
@@ -1918,11 +1926,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
                                                }
 
                                                engine->last_ts = engine->read_frame.timestamp;
+                                               engine->last_seq = engine->read_frame.seq;
 
 
                                        } else {
                                                engine->mismatch_count = 0;
                                                engine->last_ts = 0;
+                                               engine->last_seq = 0;
                                        }
                                }
 
@@ -4560,6 +4570,7 @@ SWITCH_DECLARE(void) switch_core_media_reset_autofix(switch_core_session_t *sess
 
        engine->check_frames = 0;
        engine->last_ts = 0;
+       engine->last_seq = 0;
 }