falconia has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-abis/+/41164?usp=email )
Change subject: trau2rtp CSD: add option to emit TW-TS-007 payloads ......................................................................
trau2rtp CSD: add option to emit TW-TS-007 payloads
Setting OSMO_RTP_EXT_TWTS007 bit in st->rtp_extensions switches CSD RTP output format from standard but inefficient CLEARMODE to the compressed-CSD RTP payload format of TW-TS-007. This new mechanism is fully symmetric with already implemented mechanism that enables or disables TW-TS-001 and TW-TS-002 RTP output for FR/HR/EFR speech codecs.
Depends: I2cc2c9340f9fa5c7111447a6beef49c335fa1107 (libosmocore) Change-Id: I86d628c65104a119ef0fb9f27f5835c9a1769971 --- M TODO-RELEASE M src/trau/trau_rtp_conv.c 2 files changed, 91 insertions(+), 1 deletion(-)
Approvals: falconia: Looks good to me, approved osmith: Looks good to me, but someone else must approve laforge: Looks good to me, but someone else must approve Jenkins Builder: Verified
diff --git a/TODO-RELEASE b/TODO-RELEASE index 32849fa..ffa6ecf 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -8,3 +8,4 @@ # If any interfaces have been removed or changed since the last public release: c:r:0. #library what description / commit summary line libosmo-netif >1.6.0 stream OSMO_STREAM_{CLI,SRV}_TCP_SOCKOPT_* +libosmogsm >1.11.0 OSMO_RTP_EXT_TWTS007 definition in rtp_extensions.h diff --git a/src/trau/trau_rtp_conv.c b/src/trau/trau_rtp_conv.c index 156b57a..9d23065 100644 --- a/src/trau/trau_rtp_conv.c +++ b/src/trau/trau_rtp_conv.c @@ -1260,6 +1260,7 @@ /* * CSD support: converting TRAU frames of type 'data' to 64 kbit/s * like the RA part of TRAU, using RTP clearmode representation. + * Alternatively, emit compressed-CSD RTP payload format of TW-TS-007. */
static int trau2rtp_data_fr(uint8_t *out, size_t out_len, @@ -1286,6 +1287,34 @@ return OSMO_CLEARMODE_20MS; }
+static int trau2rtp_data_fr_ccsd(uint8_t *out, size_t out_len, + const struct osmo_trau_frame *tf) +{ + int len; + + /* function interface preliminaries */ + if (tf->type != OSMO_TRAU16_FT_DATA) + return -EINVAL; + if (out_len < OSMO_CCSD_PL_LEN_9k6) + return -ENOSPC; + + /* Is it TCH/F9.6 with 16 kbit/s IR, + * or TCH/F4.8 or TCH/F2.4 with 8 kbit/s IR? */ + if (tf->c_bits[5]) { + osmo_ccsd_pack_v110_frame(out, tf->d_bits); + osmo_ccsd_pack_v110_frame(out + 8, tf->d_bits + 63); + osmo_ccsd_pack_v110_frame(out + 16, tf->d_bits + 63 * 2); + osmo_ccsd_pack_v110_frame(out + 24, tf->d_bits + 63 * 3); + len = OSMO_CCSD_PL_LEN_9k6; + } else { + osmo_ccsd_pack_v110_frame(out, tf->d_bits); + osmo_ccsd_pack_v110_frame(out + 8, tf->d_bits + 63 * 2); + len = OSMO_CCSD_PL_LEN_4k8; + } + + return len; +} + static int trau2rtp_data_hr16(uint8_t *out, size_t out_len, const struct osmo_trau_frame *tf) { @@ -1305,8 +1334,27 @@ return OSMO_CLEARMODE_20MS; }
+static int trau2rtp_data_hr16_ccsd(uint8_t *out, size_t out_len, + const struct osmo_trau_frame *tf) +{ + /* function interface preliminaries */ + if (tf->type != OSMO_TRAU16_FT_DATA_HR) + return -EINVAL; + if (out_len < OSMO_CCSD_PL_LEN_4k8) + return -ENOSPC; + + /* Note that Osmocom trau_frame decoding and encoding API + * puts the second reduced V.110 frame at d_bits position 63, + * unlike 8 kbit/s IR in FR-data frame type where it resides + * at d_bits position 63 * 2. */ + osmo_ccsd_pack_v110_frame(out, tf->d_bits); + osmo_ccsd_pack_v110_frame(out + 8, tf->d_bits + 63); + + return OSMO_CCSD_PL_LEN_4k8; +} + static int trau2rtp_data_hr8(uint8_t *out, size_t out_len, - const struct osmo_trau_frame *tf) + const struct osmo_trau_frame *tf) { /* function interface preliminaries */ if (tf->type != OSMO_TRAU8_DATA) @@ -1320,6 +1368,21 @@ return OSMO_CLEARMODE_20MS; }
+static int trau2rtp_data_hr8_ccsd(uint8_t *out, size_t out_len, + const struct osmo_trau_frame *tf) +{ + /* function interface preliminaries */ + if (tf->type != OSMO_TRAU8_DATA) + return -EINVAL; + if (out_len < OSMO_CCSD_PL_LEN_4k8) + return -ENOSPC; + + osmo_ccsd_pack_v110_frame(out, tf->d_bits); + osmo_ccsd_pack_v110_frame(out + 8, tf->d_bits + 63); + + return OSMO_CCSD_PL_LEN_4k8; +} + static int trau2rtp_edata(uint8_t *out, size_t out_len, const struct osmo_trau_frame *tf) { @@ -1337,6 +1400,24 @@ return OSMO_CLEARMODE_20MS; }
+static int trau2rtp_edata_ccsd(uint8_t *out, size_t out_len, + const struct osmo_trau_frame *tf) +{ + /* function interface preliminaries */ + if (tf->type != OSMO_TRAU16_FT_EDATA) + return -EINVAL; + if (out_len < OSMO_CCSD_PL_LEN_14k4) + return -ENOSPC; + + /* Per TS 48.020 section 11.1: + * A-TRAU bit C4 is always 1 in BSS->IWF direction + * A-TRAU bit C5 comes from E-TRAU bit C6 */ + osmo_ccsd_pack_atrau_frame(out, tf->m_bits, tf->d_bits, 1, + tf->c_bits[5]); + + return OSMO_CCSD_PL_LEN_14k4; +} + /* * CSD in the opposite direction: from clearmode RTP input * to TRAU frame output. @@ -1700,14 +1781,22 @@ case OSMO_TRAU16_FT_HR: return trau2rtp_hr16(out, out_len, tf, check_twts002(st), ufe); case OSMO_TRAU16_FT_DATA: + if (st->rtp_extensions & OSMO_RTP_EXT_TWTS007) + return trau2rtp_data_fr_ccsd(out, out_len, tf); return trau2rtp_data_fr(out, out_len, tf); case OSMO_TRAU16_FT_DATA_HR: + if (st->rtp_extensions & OSMO_RTP_EXT_TWTS007) + return trau2rtp_data_hr16_ccsd(out, out_len, tf); return trau2rtp_data_hr16(out, out_len, tf); case OSMO_TRAU16_FT_EDATA: + if (st->rtp_extensions & OSMO_RTP_EXT_TWTS007) + return trau2rtp_edata_ccsd(out, out_len, tf); return trau2rtp_edata(out, out_len, tf); case OSMO_TRAU8_SPEECH: return trau2rtp_hr8(out, out_len, tf, check_twts002(st), ufe); case OSMO_TRAU8_DATA: + if (st->rtp_extensions & OSMO_RTP_EXT_TWTS007) + return trau2rtp_data_hr8_ccsd(out, out_len, tf); return trau2rtp_data_hr8(out, out_len, tf); default: return -EINVAL;