comparison src/rtp_tx.c @ 24:84d427017d2f

endp: implement RTP Tx
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 07 Jul 2024 07:33:48 +0000
parents
children e67b3bb87d1b
comparison
equal deleted inserted replaced
23:9e477a4b485a 24:84d427017d2f
1 /*
2 * Here we implement RTP Tx functionality.
3 */
4
5 #include <stdint.h>
6 #include <stdbool.h>
7 #include <string.h>
8 #include <errno.h>
9
10 #include <osmocom/core/msgb.h>
11 #include <osmocom/core/osmo_io.h>
12 #include <osmocom/core/timer.h>
13
14 #include <themwi/rtp/endp.h>
15 #include <themwi/rtp/rtp_basic_hdr.h>
16 #include <themwi/rtp/twjit.h>
17
18 static uint32_t gen_timestamp(struct timespec *now,
19 struct twrtp_jibuf_inst *twjit)
20 {
21 uint32_t ts;
22
23 ts = now->tv_sec * twjit->ts_units_per_sec +
24 now->tv_nsec / twjit->ns_to_ts_units;
25 return ts;
26 }
27
28 int twrtp_endp_tx_quantum(struct twrtp_endp *endp, const uint8_t *payload,
29 unsigned payload_len, uint8_t payload_type,
30 bool marker, bool send_rtcp)
31 {
32 uint32_t ts_quantum = endp->twjit->ts_quantum;
33 struct msgb *msg;
34 struct timespec now;
35 uint32_t restart_ts;
36 int32_t ts_delta;
37 struct rtp_basic_hdr *rtph;
38 uint8_t *pl_out;
39 int rc;
40
41 if (!endp->register_done || !endp->remote_set)
42 return -EINVAL;
43 msg = msgb_alloc_c(endp, sizeof(struct rtp_basic_hdr) + payload_len,
44 "ThemWi-RTP-Tx");
45 if (!msg)
46 return -ENOMEM;
47
48 /* timestamp generation is where we do some trickery */
49 osmo_clock_gettime(CLOCK_REALTIME, &now);
50 if (!endp->tx.started) {
51 endp->tx.ts = gen_timestamp(&now, endp->twjit);
52 endp->tx.started = true;
53 endp->tx.restart = false;
54 } else if (endp->tx.restart) {
55 restart_ts = gen_timestamp(&now, endp->twjit);
56 ts_delta = (int32_t)(restart_ts - endp->tx.ts);
57 if (ts_delta <= 0) {
58 /* shouldn't happen, unless something funky w/clock */
59 endp->tx.ts++;
60 } else {
61 if (ts_delta % ts_quantum == 0)
62 restart_ts++;
63 endp->tx.ts = restart_ts;
64 }
65 endp->tx.restart = false;
66 }
67
68 rtph = (struct rtp_basic_hdr *)
69 msgb_put(msg, sizeof(struct rtp_basic_hdr));
70 rtph->v_p_x_cc = 0x80;
71 rtph->m_pt = payload_type;
72 if (marker)
73 rtph->m_pt |= 0x80;
74 rtph->ssrc = endp->tx.ssrc;
75 rtph->seq = endp->tx.seq;
76 rtph->tstamp = endp->tx.ts;
77 pl_out = msgb_put(msg, payload_len);
78 memcpy(pl_out, payload, payload_len);
79 endp->tx.seq++;
80 endp->tx.ts += ts_quantum;
81
82 rc = osmo_iofd_sendto_msgb(endp->iofd_rtp, msg, 0, &endp->rtp_remote);
83 if (rc < 0) {
84 msgb_free(msg);
85 return rc;
86 }
87
88 /* TODO: send RTCP if requested */
89
90 return 0;
91 }