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