linphone-developers
[Top][All Lists]
Advanced

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

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


From: Simon Morlat
Subject: Re: [Linphone-developers] Voice quality on 3G and EDGE
Date: Thu, 09 Sep 2010 21:53:23 +0200

There is an RFC for redundancy over RTP:
http://www.rfc-archive.org/getrfc.php?rfc=2198

Instead of sending duplicates RTP packets, this RFC suggests to
retransmit past payload data together with fresh data, within a single
RTP packet.
This drastically reduces bandwidth compare to the "sending duplicates"
solution.

Simon

Le mardi 07 septembre 2010 à 09:54 +0200, Vadim Lebedev a écrit :
> 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
> 
> 
> 
> 
> _______________________________________________
> Linphone-developers mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/linphone-developers





reply via email to

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