FreeCalypso > hg > themwi-rtp-lib
annotate src/rtp_tx.c @ 33:e70e7b266f89
hook in RTCP output
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 08 Jul 2024 07:25:19 +0000 |
parents | defe58aa537c |
children |
rev | line source |
---|---|
24
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
1 /* |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
2 * Here we implement RTP Tx functionality. |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
3 */ |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
4 |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
5 #include <stdint.h> |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
6 #include <stdbool.h> |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
7 #include <string.h> |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
8 #include <errno.h> |
25
e67b3bb87d1b
RTP Tx: network byte order
Mychaela Falconia <falcon@freecalypso.org>
parents:
24
diff
changeset
|
9 #include <arpa/inet.h> /* for network byte order functions */ |
24
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
10 |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
11 #include <osmocom/core/msgb.h> |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
12 #include <osmocom/core/osmo_io.h> |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
13 #include <osmocom/core/timer.h> |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
14 |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
15 #include <themwi/rtp/endp.h> |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
16 #include <themwi/rtp/rtp_basic_hdr.h> |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
17 #include <themwi/rtp/twjit.h> |
33
e70e7b266f89
hook in RTCP output
Mychaela Falconia <falcon@freecalypso.org>
parents:
28
diff
changeset
|
18 #include "endp_internal.h" |
24
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
19 |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
20 static uint32_t gen_timestamp(struct timespec *now, |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
21 struct twrtp_jibuf_inst *twjit) |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
22 { |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
23 uint32_t ts; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
24 |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
25 ts = now->tv_sec * twjit->ts_units_per_sec + |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
26 now->tv_nsec / twjit->ns_to_ts_units; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
27 return ts; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
28 } |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
29 |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
30 int twrtp_endp_tx_quantum(struct twrtp_endp *endp, const uint8_t *payload, |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
31 unsigned payload_len, uint8_t payload_type, |
26
f71efdd08c33
RTP Tx: add auto_marker mode of operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
25
diff
changeset
|
32 bool marker, bool auto_marker, bool send_rtcp) |
24
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
33 { |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
34 uint32_t ts_quantum = endp->twjit->ts_quantum; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
35 struct msgb *msg; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
36 struct timespec now; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
37 uint32_t restart_ts; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
38 int32_t ts_delta; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
39 struct rtp_basic_hdr *rtph; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
40 uint8_t *pl_out; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
41 int rc; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
42 |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
43 if (!endp->register_done || !endp->remote_set) |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
44 return -EINVAL; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
45 msg = msgb_alloc_c(endp, sizeof(struct rtp_basic_hdr) + payload_len, |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
46 "ThemWi-RTP-Tx"); |
27
a0b89c028053
RTP Tx: implement skip operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
26
diff
changeset
|
47 if (!msg) { |
a0b89c028053
RTP Tx: implement skip operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
26
diff
changeset
|
48 twrtp_endp_tx_skip(endp); |
24
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
49 return -ENOMEM; |
27
a0b89c028053
RTP Tx: implement skip operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
26
diff
changeset
|
50 } |
24
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
51 |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
52 /* timestamp generation is where we do some trickery */ |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
53 osmo_clock_gettime(CLOCK_REALTIME, &now); |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
54 if (!endp->tx.started) { |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
55 endp->tx.ts = gen_timestamp(&now, endp->twjit); |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
56 endp->tx.started = true; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
57 endp->tx.restart = false; |
26
f71efdd08c33
RTP Tx: add auto_marker mode of operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
25
diff
changeset
|
58 if (auto_marker) |
f71efdd08c33
RTP Tx: add auto_marker mode of operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
25
diff
changeset
|
59 marker = true; |
24
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
60 } else if (endp->tx.restart) { |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
61 restart_ts = gen_timestamp(&now, endp->twjit); |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
62 ts_delta = (int32_t)(restart_ts - endp->tx.ts); |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
63 if (ts_delta <= 0) { |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
64 /* shouldn't happen, unless something funky w/clock */ |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
65 endp->tx.ts++; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
66 } else { |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
67 if (ts_delta % ts_quantum == 0) |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
68 restart_ts++; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
69 endp->tx.ts = restart_ts; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
70 } |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
71 endp->tx.restart = false; |
26
f71efdd08c33
RTP Tx: add auto_marker mode of operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
25
diff
changeset
|
72 if (auto_marker) |
f71efdd08c33
RTP Tx: add auto_marker mode of operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
25
diff
changeset
|
73 marker = true; |
24
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
74 } |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
75 |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
76 rtph = (struct rtp_basic_hdr *) |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
77 msgb_put(msg, sizeof(struct rtp_basic_hdr)); |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
78 rtph->v_p_x_cc = 0x80; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
79 rtph->m_pt = payload_type; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
80 if (marker) |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
81 rtph->m_pt |= 0x80; |
25
e67b3bb87d1b
RTP Tx: network byte order
Mychaela Falconia <falcon@freecalypso.org>
parents:
24
diff
changeset
|
82 rtph->ssrc = htonl(endp->tx.ssrc); |
e67b3bb87d1b
RTP Tx: network byte order
Mychaela Falconia <falcon@freecalypso.org>
parents:
24
diff
changeset
|
83 rtph->seq = htons(endp->tx.seq); |
e67b3bb87d1b
RTP Tx: network byte order
Mychaela Falconia <falcon@freecalypso.org>
parents:
24
diff
changeset
|
84 rtph->tstamp = htonl(endp->tx.ts); |
24
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
85 pl_out = msgb_put(msg, payload_len); |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
86 memcpy(pl_out, payload, payload_len); |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
87 endp->tx.seq++; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
88 endp->tx.ts += ts_quantum; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
89 |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
90 rc = osmo_iofd_sendto_msgb(endp->iofd_rtp, msg, 0, &endp->rtp_remote); |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
91 if (rc < 0) { |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
92 msgb_free(msg); |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
93 return rc; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
94 } |
28
defe58aa537c
RTP Tx: count stats for RTCP SR
Mychaela Falconia <falcon@freecalypso.org>
parents:
27
diff
changeset
|
95 endp->stats.tx_rtp_pkt++; |
defe58aa537c
RTP Tx: count stats for RTCP SR
Mychaela Falconia <falcon@freecalypso.org>
parents:
27
diff
changeset
|
96 endp->stats.tx_rtp_bytes += payload_len; |
24
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
97 |
33
e70e7b266f89
hook in RTCP output
Mychaela Falconia <falcon@freecalypso.org>
parents:
28
diff
changeset
|
98 if (endp->auto_rtcp_interval) { |
e70e7b266f89
hook in RTCP output
Mychaela Falconia <falcon@freecalypso.org>
parents:
28
diff
changeset
|
99 endp->auto_rtcp_count++; |
e70e7b266f89
hook in RTCP output
Mychaela Falconia <falcon@freecalypso.org>
parents:
28
diff
changeset
|
100 if (endp->auto_rtcp_count >= endp->auto_rtcp_interval) { |
e70e7b266f89
hook in RTCP output
Mychaela Falconia <falcon@freecalypso.org>
parents:
28
diff
changeset
|
101 endp->auto_rtcp_count = 0; |
e70e7b266f89
hook in RTCP output
Mychaela Falconia <falcon@freecalypso.org>
parents:
28
diff
changeset
|
102 send_rtcp = true; |
e70e7b266f89
hook in RTCP output
Mychaela Falconia <falcon@freecalypso.org>
parents:
28
diff
changeset
|
103 } |
e70e7b266f89
hook in RTCP output
Mychaela Falconia <falcon@freecalypso.org>
parents:
28
diff
changeset
|
104 } |
e70e7b266f89
hook in RTCP output
Mychaela Falconia <falcon@freecalypso.org>
parents:
28
diff
changeset
|
105 if (send_rtcp) { |
e70e7b266f89
hook in RTCP output
Mychaela Falconia <falcon@freecalypso.org>
parents:
28
diff
changeset
|
106 _twrtp_endp_send_rtcp(endp, true, &now, |
e70e7b266f89
hook in RTCP output
Mychaela Falconia <falcon@freecalypso.org>
parents:
28
diff
changeset
|
107 endp->tx.ts - ts_quantum); |
e70e7b266f89
hook in RTCP output
Mychaela Falconia <falcon@freecalypso.org>
parents:
28
diff
changeset
|
108 } |
24
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
109 |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
110 return 0; |
84d427017d2f
endp: implement RTP Tx
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
111 } |
27
a0b89c028053
RTP Tx: implement skip operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
26
diff
changeset
|
112 |
a0b89c028053
RTP Tx: implement skip operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
26
diff
changeset
|
113 void twrtp_endp_tx_skip(struct twrtp_endp *endp) |
a0b89c028053
RTP Tx: implement skip operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
26
diff
changeset
|
114 { |
a0b89c028053
RTP Tx: implement skip operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
26
diff
changeset
|
115 if (!endp->tx.started || endp->tx.restart) |
a0b89c028053
RTP Tx: implement skip operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
26
diff
changeset
|
116 return; |
a0b89c028053
RTP Tx: implement skip operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
26
diff
changeset
|
117 endp->tx.ts += endp->twjit->ts_quantum; |
a0b89c028053
RTP Tx: implement skip operation
Mychaela Falconia <falcon@freecalypso.org>
parents:
26
diff
changeset
|
118 } |