res/res_rtp_asterisk: smoother can cause wrong timestamps if dtmf happen
[asterisk/asterisk.git] / res / res_rtp_asterisk.c
index ff8e453..84b2088 100644 (file)
@@ -323,12 +323,10 @@ struct ast_rtp {
        unsigned int themssrc;          /*!< Their SSRC */
        unsigned int themssrc_valid;    /*!< True if their SSRC is available. */
        unsigned int lastts;
-       unsigned int lastrxts;
        unsigned int lastividtimestamp;
        unsigned int lastovidtimestamp;
        unsigned int lastitexttimestamp;
        unsigned int lastotexttimestamp;
-       unsigned int lasteventseqn;
        int lastrxseqno;                /*!< Last received sequence number, from the network */
        int expectedrxseqno;            /*!< Next expected sequence number, from the network */
        AST_VECTOR(, int) missing_seqno; /*!< A vector of sequence numbers we never received */
@@ -345,10 +343,6 @@ struct ast_rtp {
        struct ast_format *lasttxformat;
        struct ast_format *lastrxformat;
 
-       int rtptimeout;                 /*!< RTP timeout time (negative or zero means disabled, negative value means temporarily disabled) */
-       int rtpholdtimeout;             /*!< RTP timeout when on hold (negative or zero means disabled, negative value means temporarily disabled). */
-       int rtpkeepalive;               /*!< Send RTP comfort noice packets for keepalive */
-
        /* DTMF Reception Variables */
        char resp;                        /*!< The current digit being processed */
        unsigned int last_seqno;          /*!< The last known sequence number for any DTMF packet */
@@ -367,17 +361,11 @@ struct ast_rtp {
        struct timeval rxcore;
        struct timeval txcore;
        double drxcore;                 /*!< The double representation of the first received packet */
-       struct timeval lastrx;          /*!< timeval when we last received a packet */
        struct timeval dtmfmute;
        struct ast_smoother *smoother;
-       int *ioid;
        unsigned short seqno;           /*!< Sequence number, RFC 3550, page 13. */
-       unsigned short rxseqno;
        struct ast_sched_context *sched;
-       struct io_context *io;
-       void *data;
        struct ast_rtcp *rtcp;
-       struct ast_rtp *bridged;        /*!< Who we are Packet bridged to */
        unsigned int asymmetric_codec;  /*!< Indicate if asymmetric send/receive codecs are allowed */
 
        struct ast_rtp_instance *bundled; /*!< The RTP instance we are bundled to */
@@ -686,9 +674,12 @@ static void ast_rtp_ice_add_remote_candidate(struct ast_rtp_instance *instance,
                return;
        }
 
-       if (!rtp->ice_proposed_remote_candidates &&
-                       !(rtp->ice_proposed_remote_candidates = ao2_container_alloc(1, NULL, ice_candidate_cmp))) {
-               return;
+       if (!rtp->ice_proposed_remote_candidates) {
+               rtp->ice_proposed_remote_candidates = ao2_container_alloc_list(
+                       AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, ice_candidate_cmp);
+               if (!rtp->ice_proposed_remote_candidates) {
+                       return;
+               }
        }
 
        /* If this is going to exceed the maximum number of ICE candidates don't even add it */
@@ -1103,8 +1094,12 @@ static void ast_rtp_ice_add_cand(struct ast_rtp_instance *instance, struct ast_r
 
        pj_ice_calc_foundation(rtp->ice->real_ice->pool, &foundation, type, addr);
 
-       if (!rtp->ice_local_candidates && !(rtp->ice_local_candidates = ao2_container_alloc(1, NULL, ice_candidate_cmp))) {
-               return;
+       if (!rtp->ice_local_candidates) {
+               rtp->ice_local_candidates = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0,
+                       NULL, ice_candidate_cmp);
+               if (!rtp->ice_local_candidates) {
+                       return;
+               }
        }
 
        if (!(candidate = ao2_alloc(sizeof(*candidate), ast_rtp_ice_candidate_destroy))) {
@@ -3105,21 +3100,18 @@ static double stddev_compute(double stddev, double sample, double normdev, doubl
 
 static int create_new_socket(const char *type, int af)
 {
-       int sock = socket(af, SOCK_DGRAM, 0);
+       int sock = ast_socket_nonblock(af, SOCK_DGRAM, 0);
 
        if (sock < 0) {
-               if (!type) {
-                       type = "RTP/RTCP";
-               }
                ast_log(LOG_WARNING, "Unable to allocate %s socket: %s\n", type, strerror(errno));
-       } else {
-               ast_fd_set_flags(sock, O_NONBLOCK);
+               return sock;
+       }
+
 #ifdef SO_NO_CHECK
-               if (nochecksums) {
-                       setsockopt(sock, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
-               }
-#endif
+       if (nochecksums) {
+               setsockopt(sock, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
        }
+#endif
 
        return sock;
 }
@@ -3965,6 +3957,12 @@ static int ast_rtp_dtmf_end_with_duration(struct ast_rtp_instance *instance, cha
 
        /* Oh and we can't forget to turn off the stuff that says we are sending DTMF */
        rtp->lastts += calc_txstamp(rtp, NULL) * DTMF_SAMPLE_RATE_MS;
+
+       /* Reset the smoother as the delivery time stored in it is now out of date */
+       if (rtp->smoother) {
+               ast_smoother_free(rtp->smoother);
+               rtp->smoother = NULL;
+       }
 cleanup:
        rtp->sending_digit = 0;
        rtp->send_digit = 0;
@@ -6438,16 +6436,6 @@ static struct ast_frame *ast_rtp_interpret(struct ast_rtp_instance *instance, st
        switch (ast_format_get_type(rtp->f.subclass.format)) {
        case AST_MEDIA_TYPE_AUDIO:
                rtp->f.frametype = AST_FRAME_VOICE;
-
-               /* The marker bit set on the voice packet indicates the start
-                * of a new stream and a new time stamp. Need to reset the DTMF
-                * last sequence number and the timestamp of the last END packet.
-                */
-               if (mark) {
-                       rtp->last_seqno = 0;
-                       rtp->last_end_timestamp = 0;
-               }
-
                break;
        case AST_MEDIA_TYPE_VIDEO:
                rtp->f.frametype = AST_FRAME_VIDEO;
@@ -6462,7 +6450,6 @@ static struct ast_frame *ast_rtp_interpret(struct ast_rtp_instance *instance, st
                        ast_codec_media_type2str(ast_format_get_type(rtp->f.subclass.format)));
                return &ast_null_frame;
        }
-       rtp->rxseqno = seqno;
 
        if (rtp->dtmf_timeout && rtp->dtmf_timeout < timestamp) {
                rtp->dtmf_timeout = 0;
@@ -6478,8 +6465,6 @@ static struct ast_frame *ast_rtp_interpret(struct ast_rtp_instance *instance, st
                }
        }
 
-       rtp->lastrxts = timestamp;
-
        rtp->f.src = "RTP";
        rtp->f.mallocd = 0;
        rtp->f.datalen = res - hdrlen;
@@ -6869,7 +6854,6 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
                                ast_sockaddr_copy(&rtp->rtcp->them, &addr);
                                ast_sockaddr_set_port(&rtp->rtcp->them, ast_sockaddr_port(&addr) + 1);
                        }
-                       rtp->rxseqno = 0;
                        ast_set_flag(rtp, FLAG_NAT_ACTIVE);
                        if (rtpdebug)
                                ast_debug(0, "RTP NAT: Got audio from other end. Now sending to address %s\n",
@@ -7391,7 +7375,9 @@ static void ast_rtp_remote_address_set(struct ast_rtp_instance *instance, struct
                ast_rtp_instance_set_remote_address(mapping->instance, addr);
        }
 
-       rtp->rxseqno = 0;
+       /* Need to reset the DTMF last sequence number and the timestamp of the last END packet */
+       rtp->last_seqno = 0;
+       rtp->last_end_timestamp = 0;
 
        if (strictrtp && rtp->strict_rtp_state != STRICT_RTP_OPEN
                && !ast_sockaddr_isnull(addr) && ast_sockaddr_cmp(addr, &rtp->strict_rtp_address)) {
@@ -7500,6 +7486,10 @@ static int ast_rtp_local_bridge(struct ast_rtp_instance *instance0, struct ast_r
 
        ao2_lock(instance0);
        ast_set_flag(rtp, FLAG_NEED_MARKER_BIT | FLAG_REQ_LOCAL_BRIDGE_BIT);
+       if (rtp->smoother) {
+               ast_smoother_free(rtp->smoother);
+               rtp->smoother = NULL;
+       }
        ao2_unlock(instance0);
 
        return 0;