linphone-developers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Linphone-developers] Voice quality on 3G and EDGE


From: Vadim Lebedev
Subject: [Linphone-developers] Voice quality on 3G and EDGE
Date: Tue, 07 Sep 2010 09:54:25 +0200
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.11) Gecko/20100713 Lightning/1.0b2pre Thunderbird/3.0.6

Hello folks,

We're trying to improve mediastreamer behaviour on 3G and EDGE environments.
For this we use RTCP receiver reports to detect changes in reported jitter, bandwidth and packet losses.

Once we detect the degradation we can adopt following strategies:

1) We can start retransmitting some/all RTP packets
2) We can pack more audio per packet
3) In case of hard congestion we can stop sending media and wait until congestion resovled


Strategies 1 and 3  are pretty simple to implement.
But strategy 2 is less trivial to implement with mediastreamer.
I'm thinking to hook a reformatting filter just before the encoder this way i'll need no modifiy all aduio input drivers to
suppport variable payload size per packet.

Simon what do you think?


Thanks
Vadim
P.S. Meanwhile i'm attaching my QOS change detection patch
===============================

diff -r 2b4d9564be9b oRTP/include/ortp/rtpsession.h
--- a/oRTP/include/ortp/rtpsession.h    Fri Sep 03 19:53:00 2010 +0200
+++ b/oRTP/include/ortp/rtpsession.h    Tue Sep 07 09:51:31 2010 +0200
@@ -167,8 +167,14 @@
 typedef struct _RtpSession RtpSession;

 typedef struct _RtpQosInfos {
-    uint32_t last_reported_jitter;
-    uint32_t jitter_gradient;
+    int  curx;
+    struct {
+        uint32_t   seqnum;
+        uint32_t   interval_losses;
+        uint32_t   remote_jitter;
+        uint32_t   total_losses;
+        uint32_t   interval_packets;
+    } data[2];
 } RtpQosInfo;


@@ -202,6 +208,8 @@
     RtpSignalTable on_timestamp_jump;
     RtpSignalTable on_network_error;
     RtpSignalTable on_rtcp_bye;
+    RtpSignalTable on_qos_event;
+
     struct _OList *signal_tables;
     struct _OList *eventqs;
     msgb_allocator_t allocator;
diff -r 2b4d9564be9b oRTP/src/rtcpparse.c
--- a/oRTP/src/rtcpparse.c    Fri Sep 03 19:53:00 2010 +0200
+++ b/oRTP/src/rtcpparse.c    Tue Sep 07 09:51:31 2010 +0200
@@ -287,54 +287,103 @@
     }
 }

+static int big_change(uint32_t v1, uint32_t  v2,  int big_thresold)
+{
+    int diff = v1 - v2;
+    uint32_t mean;
+
+    mean = ((v1 + v2) / 2) ;
+
+    if (diff < 0)
+        diff = -diff;
+
+    diff = diff*100 / mean;
+
+    return diff > big_thresold;
+
+}
 /*old functions: deprecated, but some useful code parts can be reused */
/* Start from now this source code file was written by Nicola Baldo as an extension of
   the oRTP library. Copyright (C) 2005 Nicola Baldo address@hidden/

void report_block_parse(RtpSession *session, report_block_t *rb, struct timeval rcv_time_tv)
 {
-  rb->ssrc = ntohl(rb->ssrc);
+    rb->ssrc = ntohl(rb->ssrc);

-  if ( rb->ssrc != session->snd.ssrc )
+    if ( rb->ssrc != session->snd.ssrc )

-    {
- ortp_debug("Received rtcp report block related to unknown ssrc (not from us)... discarded");
-      return;
-    }
-
-  else
-
-    {
-      uint32_t rcv_time_msw;
-      uint32_t rcv_time_lsw;
-      uint32_t rcv_time;
-      double rtt;
-
-      rcv_time_msw = rcv_time_tv.tv_sec;
-#if defined(_WIN32_WCE)
- rcv_time_lsw = (uint32_t) ((double)rcv_time_tv.tv_usec*(double)(((uint64_t)1)<<32)*1.0e-6);
-#else
- rcv_time_lsw = (uint32_t) ((double)rcv_time_tv.tv_usec*(double)(1LL<<32)*1.0e-6);
-#endif
-      rcv_time = (rcv_time_msw<<16) | (rcv_time_lsw >> 16);
-
-/*
-      rb->cum_num_packet_lost = ntoh24(rb->cum_num_packet_lost);
-      rb->ext_high_seq_num_rec = ntohl(rb->ext_high_seq_num_rec);
-      rb->interarrival_jitter = ntohl(rb->interarrival_jitter);
-      rb->lsr = ntohl(rb->lsr);
-      rb->delay_snc_last_sr = ntohl(rb->delay_snc_last_sr);
-*/
-
-      /* calculating Round Trip Time*/
-      if (rb->lsr != 0)
     {
-      rtt = (double) (rcv_time - rb->delay_snc_last_sr - rb->lsr);
-      rtt = rtt/65536;
-      //printf("RTT = %f s\n",rtt);
+ ortp_debug("Received rtcp report block related to unknown ssrc (not from us)... discarded");
+        return;
     }

-    }
+    else
+
+    {
+        uint32_t rcv_time_msw;
+        uint32_t rcv_time_lsw;
+        uint32_t rcv_time;
+        double rtt;
+        int newx,curx,generate_qos_event = 0;
+
+        rcv_time_msw = rcv_time_tv.tv_sec;
+#if defined(_WIN32_WCE)
+ rcv_time_lsw = (uint32_t) ((double)rcv_time_tv.tv_usec*(double)(((uint64_t)1)<<32)*1.0e-6);
+#else
+ rcv_time_lsw = (uint32_t) ((double)rcv_time_tv.tv_usec*(double)(1LL<<32)*1.0e-6);
+#endif
+        rcv_time = (rcv_time_msw<<16) | (rcv_time_lsw >> 16);
+
+
+        rb->fl_cnpl = ntohl(rb->fl_cnpl);
+
+        rb->ext_high_seq_num_rec = ntohl(rb->ext_high_seq_num_rec);
+        rb->interarrival_jitter = ntohl(rb->interarrival_jitter);
+        rb->lsr = ntohl(rb->lsr);
+        rb->delay_snc_last_sr = ntohl(rb->delay_snc_last_sr);
+
+        curx = session->qos.curx;
+        newx = (!session->qos.data[curx].seqnum) ? 0 : !curx;
+        session->qos.data[newx].seqnum = rb->ext_high_seq_num_rec;
+        session->qos.data[newx].total_losses = rb->fl_cnpl & 0x00FFFFFF;
+        session->qos.data[newx].remote_jitter = rb->interarrival_jitter;
+        if (newx != curx) {
+            session->qos.data[newx].interval_losses =
+ session->qos.data[newx].total_losses - session->qos.data[curx].total_losses;
+
+            session->qos.data[newx].interval_packets =
+ session->qos.data[newx].seqnum - session->qos.data[curx].seqnum;
+
+
+ if (big_change(session->qos.data[newx].interval_losses, session->qos.data[curx].interval_losses, 10 ))
+                generate_qos_event++;
+
+ if (big_change(session->qos.data[newx].remote_jitter, session->qos.data[curx].remote_jitter, 10 ))
+                generate_qos_event++;
+
+ if (big_change(session->qos.data[newx].interval_packets, session->qos.data[curx].interval_packets, 10))
+                generate_qos_event++;
+
+
+
+        }
+
+
+
+        /* calculating Round Trip Time*/
+        if (rb->lsr != 0)
+        {
+            rtt = (double) (rcv_time - rb->delay_snc_last_sr - rb->lsr);
+            rtt = rtt/65536;
+            //printf("RTT = %f s\n",rtt);
+        }
+
+        if (generate_qos_event)
+            rtp_signal_table_emit(&session->on_qos_event);
+
+        session->qos.curx = newx;
+
+    }

 }

diff -r 2b4d9564be9b oRTP/src/rtpsession.c
--- a/oRTP/src/rtpsession.c    Fri Sep 03 19:53:00 2010 +0200
+++ b/oRTP/src/rtpsession.c    Tue Sep 07 09:51:31 2010 +0200
@@ -263,6 +263,8 @@
rtp_signal_table_init (&session->on_timestamp_jump,session,"timestamp_jump"); rtp_signal_table_init (&session->on_network_error,session,"network_error");
     rtp_signal_table_init (&session->on_rtcp_bye,session,"rtcp_bye");
+    rtp_signal_table_init (&session->on_qos_event,session,"qos_event");
+
     wait_point_init(&session->snd.wp);
     wait_point_init(&session->rcv.wp);
     /*defaults send payload type to 0 (pcmu)*/
diff -r 2b4d9564be9b oRTP/src/rtpsession_priv.h
--- a/oRTP/src/rtpsession_priv.h    Fri Sep 03 19:53:00 2010 +0200
+++ b/oRTP/src/rtpsession_priv.h    Tue Sep 07 09:51:31 2010 +0200
@@ -51,6 +51,6 @@

 void rtp_session_dispatch_event(RtpSession *session, OrtpEvent *ev);

-#define rtp_qos_reset(qos) { (qos)->last_reported_jitter = 0; (qos)->jitter_gradient = 0; }
+#define rtp_qos_reset(qos) { memset((qos), 0, sizeof(*(qos))); }

 #endif






reply via email to

[Prev in Thread] Current Thread [Next in Thread]