• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer RIST plugin
2  * Copyright (C) 2019 Net Insight AB
3  *     Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include "gstrist.h"
26 #include "gstroundrobin.h"
27 
28 /*
29  * rtp_ext_seq:
30  * @extseq: (inout): a previous extended seqs
31  * @seq: a new seq
32  *
33  * Update the @extseq field with the extended seq of @seq
34  * For the first call of the method, @extseq should point to a location
35  * with a value of -1.
36  *
37  * This function is able to handle both forward and backward seqs taking
38  * into account:
39  *   - seq wraparound making sure that the returned value is properly increased.
40  *   - seq unwraparound making sure that the returned value is properly decreased.
41  *
42  * Returns: The extended seq of @seq or 0 if the result can't go anywhere backwards.
43  *
44  * NOTE: This is a calque of gst_rtp_buffer_ext_timestamp() but with
45  * s/32/16/ and s/64/32/ and s/0xffffffff/0xffff/ and s/timestamp/seqnum/.
46  */
47 guint32
gst_rist_rtp_ext_seq(guint32 * extseqnum,guint16 seqnum)48 gst_rist_rtp_ext_seq (guint32 * extseqnum, guint16 seqnum)
49 {
50   guint32 result, ext;
51 
52   g_return_val_if_fail (extseqnum != NULL, -1);
53 
54   ext = *extseqnum;
55 
56   if (ext == -1) {
57     result = seqnum;
58   } else {
59     /* pick wraparound counter from previous seqnum and add to new seqnum */
60     result = seqnum + (ext & ~(0xffff));
61 
62     /* check for seqnum wraparound */
63     if (result < ext) {
64       guint32 diff = ext - result;
65 
66       if (diff > G_MAXINT16) {
67         /* seqnum went backwards more than allowed, we wrap around and get
68          * updated extended seqnum. */
69         result += (1 << 16);
70       }
71     } else {
72       guint32 diff = result - ext;
73 
74       if (diff > G_MAXINT16) {
75         if (result < (1 << 16)) {
76           GST_WARNING
77               ("Cannot unwrap, any wrapping took place yet. Returning 0 without updating extended seqnum.");
78           return 0;
79         } else {
80           /* seqnum went forwards more than allowed, we unwrap around and get
81            * updated extended seqnum. */
82           result -= (1 << 16);
83           /* We don't want the extended seqnum storage to go back, ever */
84           return result;
85         }
86       }
87     }
88   }
89 
90   *extseqnum = result;
91 
92   return result;
93 }
94