annotate src/twjit.c @ 42:334d883b96ba

twrtp_jibuf_create: make config argument const While this config structure is not a constant in the mathematical sense of the term (it is expected that vty config changes may happen while twjit instance is alive), twjit functions never write to it, only read, hence it is 'const' in the not-quite-mathematical C-standard sense.
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 20 Dec 2024 22:47:20 +0000
parents bda6b24385f7
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
5
1bb26347e253 twjit: split into separate base/in/out modules
Mychaela Falconia <falcon@freecalypso.org>
parents: 3
diff changeset
2 * Themyscira Wireless jitter buffer implementation: main body.
3
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 */
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 #include <stdint.h>
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 #include <stdbool.h>
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 #include <string.h>
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <osmocom/core/linuxlist.h>
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <osmocom/core/msgb.h>
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <osmocom/core/talloc.h>
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include <osmocom/core/utils.h>
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 #include <themwi/rtp/twjit.h>
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 void twrtp_jibuf_init_defaults(struct twrtp_jibuf_config *config)
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 {
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 memset(config, 0, sizeof(struct twrtp_jibuf_config));
41
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
19
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
20 /* While the theoretical minimum starting fill level is 1, the
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
21 * practically useful minimum (achieving lowest latency, but not
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
22 * incurring underruns in normal healthy operation) is 2 for typical
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
23 * network configurations that combine elements with "perfect" 20 ms
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
24 * timing (T1/E1 interfaces, external IP-PSTN links, software
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
25 * transcoders timed by system clock etc) and GSM-to-IP OsmoBTS
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
26 * whose 20 ms timing contains the small inherent jitter of TDMA. */
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
27 config->bd_start = 2;
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
28
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
29 /* The high water mark setting determines when the standing queue
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
30 * thinning mechanism kicks in. A standing queue that is longer
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
31 * than the starting fill level will occur when the flow starts
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
32 * during a network latency spike, but then the network latency
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
33 * goes down. If this setting is too high, deep standing queues
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
34 * will persist, adding needless latency to speech or CSD.
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
35 * If this setting is too low, the thinning mechanism will be
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
36 * too invasive, needlessly and perhaps frequently deleting a quantum
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
37 * of speech or data from the stream and incurring a phase shift.
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
38 * Starting fill level plus 2 seems like a good default. */
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
39 config->bd_hiwat = 4;
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
40
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
41 /* When the standing queue thinning mechanism does kick in,
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
42 * it drops every Nth packet, where N is the thinning interval.
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
43 * Given that this mechanism forcibly deletes a quantum of speech
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
44 * or data from the stream, these induced disruptions should be
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
45 * spaced out, and the managing operator should also keep in mind
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
46 * that the incurred phase shift may be a problem for some
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
47 * applications, particularly CSD. Our current default is
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
48 * a prime number, reducing the probability that the thinning
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
49 * mechanism will interfere badly with intrinsic features of the
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
50 * stream being thinned. 17 quantum units at 20 ms per quantum
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
51 * is 340 ms, which should be sufficiently long spacing to make
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
52 * speech quantum deletions tolerable. */
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
53 config->thinning_int = 17;
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
54
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
55 /* With RTP timestamps being 32 bits and with the usual RTP
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
56 * clock rate of 8000 timestamp units per second, a packet may
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
57 * arrive that claims to be as far as 3 days into the future.
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
58 * Such aberrant RTP packets are jocularly referred to as
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
59 * time travelers. Assuming that actual time travel either
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
60 * does not exist at all or at least does not happen in the
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
61 * present context, we reason that when such "time traveler" RTP
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
62 * packets do arrive, we must be dealing with the effect of a
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
63 * software bug or misdesign or misconfiguration in whatever
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
64 * foreign network element is sending us RTP. In any case,
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
65 * irrespective of the cause, we must be prepared for the
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
66 * possibility of seeming "time travel" in the incoming RTP stream.
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
67 * We implement an arbitrary threshold: if the received RTP ts
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
68 * is too far into the future, we treat that packet as the
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
69 * beginning of a new stream, same as SSRC change or non-quantum
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
70 * ts increment. This threshold has 1 s granularity, which is
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
71 * sufficient for its intended purpose of catching gross errors.
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
72 * The minimum setting of this threshold is 1 s, but let's
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
73 * default to 10 s, being generous to networks with really bad
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
74 * latency. */
bda6b24385f7 twjit config: revisit default settings
Mychaela Falconia <falcon@freecalypso.org>
parents: 39
diff changeset
75 config->max_future_sec = 10;
3
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 }
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 /* create and destroy functions */
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80 struct twrtp_jibuf_inst *
42
334d883b96ba twrtp_jibuf_create: make config argument const
Mychaela Falconia <falcon@freecalypso.org>
parents: 41
diff changeset
81 twrtp_jibuf_create(void *ctx, const struct twrtp_jibuf_config *config)
3
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 {
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 struct twrtp_jibuf_inst *twjit;
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 twjit = talloc_zero(ctx, struct twrtp_jibuf_inst);
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 if (!twjit)
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87 return NULL;
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89 twjit->ext_config = config;
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 twjit->state = TWJIT_STATE_EMPTY;
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 INIT_LLIST_HEAD(&twjit->sb[0].queue);
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 INIT_LLIST_HEAD(&twjit->sb[1].queue);
15
355de6301404 twjit: simplify create API, factor out clock & quantum config
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
93 /* default of 8 kHz clock, 20 ms quantum */
355de6301404 twjit: simplify create API, factor out clock & quantum config
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
94 twrtp_jibuf_set_ts_quant(twjit, 8, 20);
3
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 return twjit;
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 }
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 void twrtp_jibuf_destroy(struct twrtp_jibuf_inst *twjit)
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100 {
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 msgb_queue_free(&twjit->sb[0].queue);
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
102 msgb_queue_free(&twjit->sb[1].queue);
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103 talloc_free(twjit);
d10ea5dc61b3 twjit: initial import from previous work repository
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104 }
15
355de6301404 twjit: simplify create API, factor out clock & quantum config
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
105
355de6301404 twjit: simplify create API, factor out clock & quantum config
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
106 /* basic housekeeping */
355de6301404 twjit: simplify create API, factor out clock & quantum config
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
107
355de6301404 twjit: simplify create API, factor out clock & quantum config
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
108 void twrtp_jibuf_set_ts_quant(struct twrtp_jibuf_inst *twjit,
355de6301404 twjit: simplify create API, factor out clock & quantum config
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
109 uint16_t clock_khz, uint16_t quantum_ms)
355de6301404 twjit: simplify create API, factor out clock & quantum config
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
110 {
355de6301404 twjit: simplify create API, factor out clock & quantum config
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
111 twjit->ts_quantum = (uint32_t) quantum_ms * clock_khz;
355de6301404 twjit: simplify create API, factor out clock & quantum config
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
112 twjit->quanta_per_sec = 1000 / quantum_ms;
355de6301404 twjit: simplify create API, factor out clock & quantum config
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
113 twjit->ts_units_per_ms = clock_khz;
355de6301404 twjit: simplify create API, factor out clock & quantum config
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
114 twjit->ts_units_per_sec = (uint32_t) clock_khz * 1000;
355de6301404 twjit: simplify create API, factor out clock & quantum config
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
115 twjit->ns_to_ts_units = 1000000 / clock_khz;
355de6301404 twjit: simplify create API, factor out clock & quantum config
Mychaela Falconia <falcon@freecalypso.org>
parents: 8
diff changeset
116 }
16
58e9719d1a84 twjit: add reset function
Mychaela Falconia <falcon@freecalypso.org>
parents: 15
diff changeset
117
58e9719d1a84 twjit: add reset function
Mychaela Falconia <falcon@freecalypso.org>
parents: 15
diff changeset
118 void twrtp_jibuf_reset(struct twrtp_jibuf_inst *twjit)
58e9719d1a84 twjit: add reset function
Mychaela Falconia <falcon@freecalypso.org>
parents: 15
diff changeset
119 {
58e9719d1a84 twjit: add reset function
Mychaela Falconia <falcon@freecalypso.org>
parents: 15
diff changeset
120 msgb_queue_free(&twjit->sb[0].queue);
58e9719d1a84 twjit: add reset function
Mychaela Falconia <falcon@freecalypso.org>
parents: 15
diff changeset
121 msgb_queue_free(&twjit->sb[1].queue);
58e9719d1a84 twjit: add reset function
Mychaela Falconia <falcon@freecalypso.org>
parents: 15
diff changeset
122 twjit->state = TWJIT_STATE_EMPTY;
58e9719d1a84 twjit: add reset function
Mychaela Falconia <falcon@freecalypso.org>
parents: 15
diff changeset
123 twjit->sb[0].depth = 0;
58e9719d1a84 twjit: add reset function
Mychaela Falconia <falcon@freecalypso.org>
parents: 15
diff changeset
124 twjit->sb[1].depth = 0;
58e9719d1a84 twjit: add reset function
Mychaela Falconia <falcon@freecalypso.org>
parents: 15
diff changeset
125 twjit->got_first_packet = false;
58e9719d1a84 twjit: add reset function
Mychaela Falconia <falcon@freecalypso.org>
parents: 15
diff changeset
126 }