]> git.sesse.net Git - vlc/blobdiff - modules/demux/rtpsession.c
Less memleaks in Qt interface.
[vlc] / modules / demux / rtpsession.c
index 65ae1daccbdb5768c1c6cd8c4b1c21d3ec30febf..ccad2841a4a1cf045daea351b631f628a2cb36cb 100644 (file)
@@ -87,7 +87,8 @@ void rtp_session_destroy (demux_t *demux, rtp_session_t *session)
 
 static void *no_init (demux_t *demux)
 {
-    return demux;
+    (void)demux;
+    return NULL;
 }
 
 static void no_destroy (demux_t *demux, void *opaque)
@@ -124,6 +125,8 @@ int rtp_add_type (demux_t *demux, rtp_session_t *ses, const rtp_pt_t *pt)
     ppt->decode = pt->decode ? pt->decode : no_decode;
     ppt->frequency = pt->frequency;
     ppt->number = pt->number;
+    msg_Dbg (demux, "added payload type %"PRIu8" (f = %"PRIu32" Hz)",
+             ppt->number, ppt->frequency);
 
     assert (ppt->frequency > 0); /* SIGFPE! */
     (void)demux;
@@ -138,8 +141,9 @@ struct rtp_source_t
     uint16_t bad_seq; /* tentatively next expected sequence for resync */
     uint16_t max_seq; /* next expected sequence */
 
+    uint16_t last_seq; /* sequence of the last dequeued packet */
     block_t *blocks; /* re-ordered blocks queue */
-    void    *opaque[0]; /* Per-source prviate payload data */
+    void    *opaque[0]; /* Per-source private payload data */
 };
 
 /**
@@ -157,6 +161,7 @@ rtp_source_create (demux_t *demux, const rtp_session_t *session,
 
     source->ssrc = ssrc;
     source->max_seq = source->bad_seq = init_seq;
+    source->last_seq = init_seq - 1;
     source->blocks = NULL;
 
     /* Initializes all payload */
@@ -263,6 +268,13 @@ rtp_receive (demux_t *demux, rtp_session_t *session, block_t *block)
         tab[session->srcc++] = src;
     }
 
+    /* Be optimistic for the first packet. Certain codec, such as Vorbis
+     * do not like loosing the first packet(s), so we cannot just wait
+     * for proper sequence synchronization. And we don't want to assume that
+     * the sender starts at seq=0 either. */
+    if (src->blocks == NULL)
+        src->max_seq = seq - p_sys->max_dropout;
+
     /* Check sequence number */
     /* NOTE: the sequence number is per-source,
      * but is independent from the payload type. */
@@ -285,13 +297,16 @@ rtp_receive (demux_t *demux, rtp_session_t *session, block_t *block)
             goto drop;
         }
     }
+    else
+    if (delta_seq < 0x8000)
+        src->max_seq = seq;
 
     /* Queues the block in sequence order,
      * hence there is a single queue for all payload types. */
     block_t **pp = &src->blocks;
     for (block_t *prev = *pp; prev != NULL; prev = *pp)
     {
-        if ((int16_t)(seq - rtp_seq (*pp)) >= 0)
+        if ((int16_t)(seq - rtp_seq (*pp)) < 0)
             break;
         pp = &prev->p_next;
     }
@@ -318,6 +333,11 @@ rtp_decode (demux_t *demux, const rtp_session_t *session, rtp_source_t *src)
     src->blocks = block->p_next;
     block->p_next = NULL;
 
+    /* Discontinuity detection */
+    if (((src->last_seq + 1) & 0xffff) != rtp_seq (block))
+        block->i_flags |= BLOCK_FLAG_DISCONTINUITY;
+    src->last_seq = rtp_seq (block);
+
     /* Match the payload type */
     const rtp_pt_t *pt = NULL;
     void *pt_data = NULL;
@@ -347,7 +367,6 @@ rtp_decode (demux_t *demux, const rtp_session_t *session, rtp_source_t *src)
     /* TODO: sync multiple sources sanely... */
     const uint32_t timestamp = GetDWBE (block->p_buffer + 4);
     block->i_pts = UINT64_C(1) * CLOCK_FREQ * timestamp / pt->frequency;
-    //msg_Dbg (demux, "pts = %"PRIu64, block->i_pts);
 
     /* CSRC count */
     size_t skip = 12u + (block->p_buffer[0] & 0x0F) * 4;