FreeCalypso > hg > themwi-rtp-lib
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 } |