session.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:15k
源码类别:

midi

开发平台:

Unix_Linux

  1. /**
  2.  * @file session.c
  3.  * @brief RTP session handling
  4.  */
  5. /*****************************************************************************
  6.  * Copyright © 2008 Rémi Denis-Courmont
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU General Public License
  10.  * as published by the Free Software Foundation; either version 2.0
  11.  * of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Lesser General Public
  19.  * License along with this library; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  21.  ****************************************************************************/
  22. #ifdef HAVE_CONFIG_H
  23. # include <config.h>
  24. #endif
  25. #include <stdlib.h>
  26. #include <assert.h>
  27. #include <errno.h>
  28. #include <vlc/vlc.h>
  29. #include <vlc_demux.h>
  30. #include "rtp.h"
  31. typedef struct rtp_source_t rtp_source_t;
  32. /** State for a RTP session: */
  33. struct rtp_session_t
  34. {
  35.     rtp_source_t **srcv;
  36.     unsigned       srcc;
  37.     uint8_t        ptc;
  38.     rtp_pt_t      *ptv;
  39. };
  40. static rtp_source_t *
  41. rtp_source_create (demux_t *, const rtp_session_t *, uint32_t, uint16_t);
  42. static void
  43. rtp_source_destroy (demux_t *, const rtp_session_t *, rtp_source_t *);
  44. static void rtp_decode (demux_t *, const rtp_session_t *, rtp_source_t *);
  45. /**
  46.  * Creates a new RTP session.
  47.  */
  48. rtp_session_t *
  49. rtp_session_create (demux_t *demux)
  50. {
  51.     rtp_session_t *session = malloc (sizeof (*session));
  52.     if (session == NULL)
  53.         return NULL;
  54.     session->srcv = NULL;
  55.     session->srcc = 0;
  56.     session->ptc = 0;
  57.     session->ptv = NULL;
  58.     (void)demux;
  59.     return session;
  60. }
  61. /**
  62.  * Destroys an RTP session.
  63.  */
  64. void rtp_session_destroy (demux_t *demux, rtp_session_t *session)
  65. {
  66.     for (unsigned i = 0; i < session->srcc; i++)
  67.         rtp_source_destroy (demux, session, session->srcv[i]);
  68.     free (session->srcv);
  69.     free (session->ptv);
  70.     free (session);
  71.     (void)demux;
  72. }
  73. static void *no_init (demux_t *demux)
  74. {
  75.     (void)demux;
  76.     return NULL;
  77. }
  78. static void no_destroy (demux_t *demux, void *opaque)
  79. {
  80.     (void)demux; (void)opaque;
  81. }
  82. static void no_decode (demux_t *demux, void *opaque, block_t *block)
  83. {
  84.     (void)demux; (void)opaque;
  85.     block_Release (block);
  86. }
  87. /**
  88.  * Adds a payload type to an RTP session.
  89.  */
  90. int rtp_add_type (demux_t *demux, rtp_session_t *ses, const rtp_pt_t *pt)
  91. {
  92.     if (ses->srcc > 0)
  93.     {
  94.         msg_Err (demux, "cannot change RTP payload formats during session");
  95.         return EINVAL;
  96.     }
  97.     rtp_pt_t *ppt = realloc (ses->ptv, (ses->ptc + 1) * sizeof (rtp_pt_t));
  98.     if (ppt == NULL)
  99.         return ENOMEM;
  100.     ses->ptv = ppt;
  101.     ppt += ses->ptc++;
  102.     ppt->init = pt->init ? pt->init : no_init;
  103.     ppt->destroy = pt->destroy ? pt->destroy : no_destroy;
  104.     ppt->decode = pt->decode ? pt->decode : no_decode;
  105.     ppt->frequency = pt->frequency;
  106.     ppt->number = pt->number;
  107.     msg_Dbg (demux, "added payload type %"PRIu8" (f = %"PRIu32" Hz)",
  108.              ppt->number, ppt->frequency);
  109.     assert (ppt->frequency > 0); /* SIGFPE! */
  110.     (void)demux;
  111.     return 0;
  112. }
  113. /** State for an RTP source */
  114. struct rtp_source_t
  115. {
  116.     uint32_t ssrc;
  117.     uint32_t jitter;  /* interarrival delay jitter estimate */
  118.     mtime_t  last_rx; /* last received packet local timestamp */
  119.     uint32_t last_ts; /* last received packet RTP timestamp */
  120.     uint16_t bad_seq; /* tentatively next expected sequence for resync */
  121.     uint16_t max_seq; /* next expected sequence */
  122.     uint16_t last_seq; /* sequence of the next dequeued packet */
  123.     block_t *blocks; /* re-ordered blocks queue */
  124.     mtime_t  ref_ts; /* reference timestamp for reordering */
  125.     void    *opaque[0]; /* Per-source private payload data */
  126. };
  127. /**
  128.  * Initializes a new RTP source within an RTP session.
  129.  */
  130. static rtp_source_t *
  131. rtp_source_create (demux_t *demux, const rtp_session_t *session,
  132.                    uint32_t ssrc, uint16_t init_seq)
  133. {
  134.     rtp_source_t *source;
  135.     source = malloc (sizeof (*source) + (sizeof (void *) * session->ptc));
  136.     if (source == NULL)
  137.         return NULL;
  138.     source->ssrc = ssrc;
  139.     source->jitter = 0;
  140.     source->ref_ts = 0;
  141.     source->max_seq = source->bad_seq = init_seq;
  142.     source->last_seq = init_seq - 1;
  143.     source->blocks = NULL;
  144.     /* Initializes all payload */
  145.     for (unsigned i = 0; i < session->ptc; i++)
  146.         source->opaque[i] = session->ptv[i].init (demux);
  147.     msg_Dbg (demux, "added RTP source (%08x)", ssrc);
  148.     return source;
  149. }
  150. /**
  151.  * Destroys an RTP source and its associated streams.
  152.  */
  153. static void
  154. rtp_source_destroy (demux_t *demux, const rtp_session_t *session,
  155.                     rtp_source_t *source)
  156. {
  157.     msg_Dbg (demux, "removing RTP source (%08x)", source->ssrc);
  158.     for (unsigned i = 0; i < session->ptc; i++)
  159.         session->ptv[i].destroy (demux, source->opaque[i]);
  160.     block_ChainRelease (source->blocks);
  161.     free (source);
  162. }
  163. static inline uint16_t rtp_seq (const block_t *block)
  164. {
  165.     assert (block->i_buffer >= 4);
  166.     return GetWBE (block->p_buffer + 2);
  167. }
  168. static inline uint32_t rtp_timestamp (const block_t *block)
  169. {
  170.     assert (block->i_buffer >= 12);
  171.     return GetDWBE (block->p_buffer + 4);
  172. }
  173. static const struct rtp_pt_t *
  174. rtp_find_ptype (const rtp_session_t *session, rtp_source_t *source,
  175.                 const block_t *block, void **pt_data)
  176. {
  177.     uint8_t ptype = rtp_ptype (block);
  178.     for (unsigned i = 0; i < session->ptc; i++)
  179.     {
  180.         if (session->ptv[i].number == ptype)
  181.         {
  182.             if (pt_data != NULL)
  183.                 *pt_data = source->opaque[i];
  184.             return &session->ptv[i];
  185.         }
  186.     }
  187.     return NULL;
  188. }
  189. /**
  190.  * Receives an RTP packet and queues it. Not a cancellation point.
  191.  *
  192.  * @param demux VLC demux object
  193.  * @param session RTP session receiving the packet
  194.  * @param block RTP packet including the RTP header
  195.  */
  196. void
  197. rtp_queue (demux_t *demux, rtp_session_t *session, block_t *block)
  198. {
  199.     demux_sys_t *p_sys = demux->p_sys;
  200.     /* RTP header sanity checks (see RFC 3550) */
  201.     if (block->i_buffer < 12)
  202.         goto drop;
  203.     if ((block->p_buffer[0] >> 6 ) != 2) /* RTP version number */
  204.         goto drop;
  205.     /* Remove padding if present */
  206.     if (block->p_buffer[0] & 0x20)
  207.     {
  208.         uint8_t padding = block->p_buffer[block->i_buffer - 1];
  209.         if ((padding == 0) || (block->i_buffer < (12u + padding)))
  210.             goto drop; /* illegal value */
  211.         block->i_buffer -= padding;
  212.     }
  213.     mtime_t        now = mdate ();
  214.     rtp_source_t  *src  = NULL;
  215.     const uint16_t seq  = rtp_seq (block);
  216.     const uint32_t ssrc = GetDWBE (block->p_buffer + 8);
  217.     /* In most case, we know this source already */
  218.     for (unsigned i = 0, max = session->srcc; i < max; i++)
  219.     {
  220.         rtp_source_t *tmp = session->srcv[i];
  221.         if (tmp->ssrc == ssrc)
  222.         {
  223.             src = tmp;
  224.             break;
  225.         }
  226.         /* RTP source garbage collection */
  227.         if ((tmp->last_rx + (p_sys->timeout * CLOCK_FREQ)) < now)
  228.         {
  229.             rtp_source_destroy (demux, session, tmp);
  230.             if (--session->srcc > 0)
  231.                 session->srcv[i] = session->srcv[session->srcc - 1];
  232.         }
  233.     }
  234.     if (src == NULL)
  235.     {
  236.         /* New source */
  237.         if (session->srcc >= p_sys->max_src)
  238.         {
  239.             msg_Warn (demux, "too many RTP sessions");
  240.             goto drop;
  241.         }
  242.         rtp_source_t **tab;
  243.         tab = realloc (session->srcv, (session->srcc + 1) * sizeof (*tab));
  244.         if (tab == NULL)
  245.             goto drop;
  246.         session->srcv = tab;
  247.         src = rtp_source_create (demux, session, ssrc, seq);
  248.         if (src == NULL)
  249.             goto drop;
  250.         tab[session->srcc++] = src;
  251.         /* Cannot compute jitter yet */
  252.     }
  253.     else
  254.     {
  255.         const rtp_pt_t *pt = rtp_find_ptype (session, src, block, NULL);
  256.         if (pt != NULL)
  257.         {
  258.             /* Recompute jitter estimate.
  259.              * That is computed from the RTP timestamps and the system clock.
  260.              * It is independent of RTP sequence. */
  261.             uint32_t freq = pt->frequency;
  262.             int64_t ts = rtp_timestamp (block);
  263.             int64_t d = ((now - src->last_rx) * freq) / CLOCK_FREQ;
  264.             d        -=    ts - src->last_ts;
  265.             if (d < 0) d = -d;
  266.             src->jitter += ((d - src->jitter) + 8) >> 4;
  267.         }
  268.     }
  269.     src->last_rx = now;
  270.     src->last_ts = rtp_timestamp (block);
  271.     /* Check sequence number */
  272.     /* NOTE: the sequence number is per-source,
  273.      * but is independent from the payload type. */
  274.     int16_t delta_seq = seq - src->max_seq;
  275.     if ((delta_seq > 0) ? (delta_seq > p_sys->max_dropout)
  276.                         : (-delta_seq > p_sys->max_misorder))
  277.     {
  278.         msg_Dbg (demux, "sequence discontinuity"
  279.                  " (got: %"PRIu16", expected: %"PRIu16")", seq, src->max_seq);
  280.         if (seq == src->bad_seq)
  281.         {
  282.             src->max_seq = src->bad_seq = seq + 1;
  283.             src->last_seq = seq - 0x7fffe; /* hack for rtp_decode() */
  284.             msg_Warn (demux, "sequence resynchronized");
  285.             block_ChainRelease (src->blocks);
  286.             src->blocks = NULL;
  287.         }
  288.         else
  289.         {
  290.             src->bad_seq = seq + 1;
  291.             goto drop;
  292.         }
  293.     }
  294.     else
  295.     if (delta_seq >= 0)
  296.         src->max_seq = seq + 1;
  297.     /* Queues the block in sequence order,
  298.      * hence there is a single queue for all payload types. */
  299.     block_t **pp = &src->blocks;
  300.     for (block_t *prev = *pp; prev != NULL; prev = *pp)
  301.     {
  302.         int16_t delta_seq = seq - rtp_seq (prev);
  303.         if (delta_seq < 0)
  304.             break;
  305.         if (delta_seq == 0)
  306.         {
  307.             msg_Dbg (demux, "duplicate packet (sequence: %"PRIu16")", seq);
  308.             goto drop; /* duplicate */
  309.         }
  310.         pp = &prev->p_next;
  311.     }
  312.     block->p_next = *pp;
  313.     *pp = block;
  314.     /*rtp_decode (demux, session, src);*/
  315.     return;
  316. drop:
  317.     block_Release (block);
  318. }
  319. static void
  320. rtp_decode (demux_t *demux, const rtp_session_t *session, rtp_source_t *src)
  321. {
  322.     block_t *block = src->blocks;
  323.     assert (block);
  324.     src->blocks = block->p_next;
  325.     block->p_next = NULL;
  326.     /* Discontinuity detection */
  327.     uint16_t delta_seq = rtp_seq (block) - (src->last_seq + 1);
  328.     if (delta_seq != 0)
  329.     {
  330.         if (delta_seq >= 0x8000)
  331.         {   /* Trash too late packets (and PIM Assert duplicates) */
  332.             msg_Dbg (demux, "ignoring late packet (sequence: %"PRIu16")",
  333.                       rtp_seq (block));
  334.             goto drop;
  335.         }
  336.         msg_Warn (demux, "%"PRIu16" packet(s) lost", delta_seq);
  337.         block->i_flags |= BLOCK_FLAG_DISCONTINUITY;
  338.     }
  339.     src->last_seq = rtp_seq (block);
  340.     /* Match the payload type */
  341.     void *pt_data;
  342.     const rtp_pt_t *pt = rtp_find_ptype (session, src, block, &pt_data);
  343.     if (pt == NULL)
  344.     {
  345.         msg_Dbg (demux, "unknown payload (%"PRIu8")",
  346.                  rtp_ptype (block));
  347.         goto drop;
  348.     }
  349.     /* Computes the PTS from the RTP timestamp and payload RTP frequency.
  350.      * DTS is unknown. Also, while the clock frequency depends on the payload
  351.      * format, a single source MUST only use payloads of a chosen frequency.
  352.      * Otherwise it would be impossible to compute consistent timestamps. */
  353.     /* FIXME: handle timestamp wrap properly */
  354.     /* TODO: inter-medias/sessions sync (using RTCP-SR) */
  355.     const uint32_t timestamp = rtp_timestamp (block);
  356.     src->ref_ts = 0;
  357.     block->i_pts = UINT64_C(1) * CLOCK_FREQ * timestamp / pt->frequency;
  358.     /* CSRC count */
  359.     size_t skip = 12u + (block->p_buffer[0] & 0x0F) * 4;
  360.     /* Extension header (ignored for now) */
  361.     if (block->p_buffer[0] & 0x10)
  362.     {
  363.         skip += 4;
  364.         if (block->i_buffer < skip)
  365.             goto drop;
  366.         skip += 4 * GetWBE (block->p_buffer + skip - 2);
  367.     }
  368.     if (block->i_buffer < skip)
  369.         goto drop;
  370.     block->p_buffer += skip;
  371.     block->i_buffer -= skip;
  372.     pt->decode (demux, pt_data, block);
  373.     return;
  374. drop:
  375.     block_Release (block);
  376. }
  377. /**
  378.  * Dequeues an RTP packet and pass it to decoder. Not cancellation-safe(?).
  379.  *
  380.  * @param demux VLC demux object
  381.  * @param session RTP session receiving the packet
  382.  * @param deadlinep pointer to deadline to call rtp_dequeue() again
  383.  * @return true if the buffer is not empty, false otherwise.
  384.  * In the later case, *deadlinep is undefined.
  385.  */
  386. bool rtp_dequeue (demux_t *demux, const rtp_session_t *session,
  387.                   mtime_t *restrict deadlinep)
  388. {
  389.     mtime_t now = mdate ();
  390.     bool pending = false;
  391.     for (unsigned i = 0, max = session->srcc; i < max; i++)
  392.     {
  393.         rtp_source_t *src = session->srcv[i];
  394.         block_t *block;
  395.         /* Because of IP packet delay variation (IPDV), we need to guesstimate
  396.          * how long to wait for a missing packet in the RTP sequence
  397.          * (see RFC3393 for background on IPDV).
  398.          *
  399.          * This situation occurs if a packet got lost, or if the network has
  400.          * re-ordered packets. Unfortunately, the MSL is 2 minutes, orders of
  401.          * magnitude too long for multimedia. We need a tradeoff.
  402.          * If we underestimated IPDV, we may have to discard valid but late
  403.          * packets. If we overestimate it, we will either cause too much
  404.          * delay, or worse, underflow our downstream buffers, as we wait for
  405.          * definitely a lost packets.
  406.          *
  407.          * The rest of the "de-jitter buffer" work is done by the interval
  408.          * LibVLC E/S-out clock synchronization. Here, we need to bother about
  409.          * re-ordering packets, as decoders can't cope with mis-ordered data.
  410.          */
  411.         while (((block = src->blocks)) != NULL)
  412.         {
  413.             if ((int16_t)(rtp_seq (block) - (src->last_seq + 1)) <= 0)
  414.             {   /* Next (or earlier) block ready, no need to wait */
  415.                 rtp_decode (demux, session, src);
  416.                 continue;
  417.             }
  418.             /* Wait for 3 times the inter-arrival delay variance (about 99.7%
  419.              * match for random gaussian jitter). Additionnaly, we implicitly
  420.              * wait for misordering times the packetization time.
  421.              */
  422.             mtime_t deadline = src->ref_ts;
  423.             const rtp_pt_t *pt = rtp_find_ptype (session, src, block, NULL);
  424.             if (!deadline)
  425.                 deadline = src->ref_ts = now;
  426.             if (pt)
  427.                 deadline += UINT64_C(3) * CLOCK_FREQ * src->jitter
  428.                             / pt->frequency;
  429.             /* Make sure we wait at least for 25 msec */
  430.             deadline = __MAX(deadline, src->ref_ts + CLOCK_FREQ / 40);
  431.             if (now >= deadline)
  432.             {
  433.                 rtp_decode (demux, session, src);
  434.                 continue;
  435.             }
  436.             if (*deadlinep > deadline)
  437.                 *deadlinep = deadline;
  438.             pending = true; /* packet pending in buffer */
  439.             break;
  440.         }
  441.     }
  442.     return pending;
  443. }