This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
laforge gerrit-no-reply at lists.osmocom.orglaforge has submitted this change. ( https://gerrit.osmocom.org/c/mncc-python/+/17978 )
Change subject: rtpsource: Modularize generation of RTP frames
......................................................................
rtpsource: Modularize generation of RTP frames
Change-Id: Iad98e1753fef1927c0e8a7493372141372a38224
---
M rtpsource/Makefile
M rtpsource/internal.h
A rtpsource/rtp_provider.c
A rtpsource/rtp_provider.h
A rtpsource/rtp_provider_static.c
M rtpsource/rtpsource.c
6 files changed, 230 insertions(+), 7 deletions(-)
Approvals:
osmith: Verified
laforge: Looks good to me, approved
diff --git a/rtpsource/Makefile b/rtpsource/Makefile
index 9972325..2ede792 100644
--- a/rtpsource/Makefile
+++ b/rtpsource/Makefile
@@ -4,7 +4,7 @@
CFLAGS:= -g -Wall $(OSMO_CFLAGS)
LIBS:= $(OSMO_LIBS)
-rtpsource: rtpsource.o ctrl_if.o
+rtpsource: rtpsource.o ctrl_if.o rtp_provider.o rtp_provider_static.o
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
diff --git a/rtpsource/internal.h b/rtpsource/internal.h
index 13d07aa..a4501a2 100644
--- a/rtpsource/internal.h
+++ b/rtpsource/internal.h
@@ -8,6 +8,8 @@
DMAIN,
};
+struct rtp_provider_instance;
+
struct rtp_connection {
struct llist_head list;
@@ -21,6 +23,7 @@
uint16_t remote_port;
uint8_t rtp_pt;
+ struct rtp_provider_instance *rtp_prov_inst;
};
struct rtpsource_state {
diff --git a/rtpsource/rtp_provider.c b/rtpsource/rtp_provider.c
new file mode 100644
index 0000000..0d2b9c6
--- /dev/null
+++ b/rtpsource/rtp_provider.c
@@ -0,0 +1,54 @@
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/linuxlist.h>
+
+#include "rtp_provider.h"
+#include "internal.h"
+
+
+static LLIST_HEAD(g_providers);
+static LLIST_HEAD(g_prov_instances);
+
+void rtp_provider_register(struct rtp_provider *prov)
+{
+ llist_add_tail(&prov->list, &g_providers);
+}
+
+const struct rtp_provider *rtp_provider_find(const char *name)
+{
+ struct rtp_provider *p;
+ llist_for_each_entry(p, &g_providers, list) {
+ if (!strcmp(name, p->name))
+ return p;
+ }
+ LOGP(DMAIN, LOGL_ERROR, "Couldn't find RTP provider '%s'\n", name);
+ return NULL;
+}
+
+struct rtp_provider_instance *
+rtp_provider_instance_alloc(void *ctx, const struct rtp_provider *provider, enum codec_type codec)
+{
+ struct rtp_provider_instance *pi;
+
+ pi = talloc_zero(ctx, struct rtp_provider_instance);
+ if (!pi)
+ return NULL;
+
+ pi->provider = provider;
+ pi->codec = codec;
+ llist_add_tail(&pi->list, &g_prov_instances);
+
+ return pi;
+}
+
+void rtp_provider_instance_free(struct rtp_provider_instance *pi)
+{
+ llist_del(&pi->list);
+ talloc_free(pi);
+}
+
+int rtp_provider_instance_gen_frame(struct rtp_provider_instance *pi, uint8_t *out, size_t out_size)
+{
+ OSMO_ASSERT(pi->provider);
+ return pi->provider->rtp_gen(pi, out, out_size);
+}
diff --git a/rtpsource/rtp_provider.h b/rtpsource/rtp_provider.h
new file mode 100644
index 0000000..7048a3e
--- /dev/null
+++ b/rtpsource/rtp_provider.h
@@ -0,0 +1,51 @@
+#pragma once
+#include <stdint.h>
+#include <osmocom/core/linuxlist.h>
+
+enum codec_type {
+ CODEC_ULAW,
+ CODEC_ALAW,
+ CODEC_GSM_FR,
+ CODEC_GSM_EFR,
+ CODEC_GSM_HR,
+ CODEC_AMR_4_75,
+ CODEC_AMR_5_15,
+ CODEC_AMR_5_90,
+ CODEC_AMR_6_70,
+ CODEC_AMR_7_40,
+ CODEC_AMR_7_95,
+ CODEC_AMR_10_2,
+ CODEC_AMR_12_2,
+ CODEC_AMR_SID,
+ _NUM_CODECS
+};
+
+struct rtp_provider_instance;
+
+struct rtp_provider {
+ /* global list of RTP providers */
+ struct llist_head list;
+ const char *name;
+
+ /* generate the next RTP packet; return length in octests or negative on error */
+ int (*rtp_gen)(struct rtp_provider_instance *inst, uint8_t *out, size_t out_size);
+};
+
+struct rtp_provider_instance {
+ /* entry in global list of RTP provider instances */
+ struct llist_head list;
+ /* pointer to provider of which we are an instance */
+ const struct rtp_provider *provider;
+ /* codec payload we are to generate */
+ enum codec_type codec;
+
+ /* private user data */
+ void *priv;
+};
+
+void rtp_provider_register(struct rtp_provider *prov);
+const struct rtp_provider *rtp_provider_find(const char *name);
+
+struct rtp_provider_instance *rtp_provider_instance_alloc(void *ctx, const struct rtp_provider *provider, enum codec_type codec);
+void rtp_provider_instance_free(struct rtp_provider_instance *pi);
+int rtp_provider_instance_gen_frame(struct rtp_provider_instance *pi, uint8_t *out, size_t out_size);
diff --git a/rtpsource/rtp_provider_static.c b/rtpsource/rtp_provider_static.c
new file mode 100644
index 0000000..323e686
--- /dev/null
+++ b/rtpsource/rtp_provider_static.c
@@ -0,0 +1,107 @@
+
+#include <errno.h>
+#include <osmocom/codec/codec.h>
+#include <osmocom/core/utils.h>
+
+#include "rtp_provider.h"
+#include "internal.h"
+
+static struct rtp_provider static_provider;
+
+static const uint8_t len4codec[_NUM_CODECS] = {
+ [CODEC_ULAW] = 160,
+ [CODEC_ALAW] = 160,
+ [CODEC_GSM_FR] = GSM_FR_BYTES,
+ [CODEC_GSM_EFR] = GSM_EFR_BYTES,
+ [CODEC_GSM_HR] = GSM_HR_BYTES,
+ [CODEC_AMR_4_75] = 12,
+ [CODEC_AMR_5_15] = 13,
+ [CODEC_AMR_5_90] = 15,
+ [CODEC_AMR_6_70] = 17,
+ [CODEC_AMR_7_40] = 19,
+ [CODEC_AMR_7_95] = 20,
+ [CODEC_AMR_10_2] = 26,
+ [CODEC_AMR_12_2] = 31,
+ [CODEC_AMR_SID] = 5,
+};
+
+/* generate a static / fixed RTP payload of matching codec/mode */
+static int rtp_gen_static(struct rtp_provider_instance *pi, uint8_t *out, size_t out_size)
+{
+ uint8_t len;
+
+ OSMO_ASSERT(pi->provider == &static_provider);
+
+ len = len4codec[pi->codec];
+ if (out_size < len) {
+ LOGP(DMAIN, LOGL_ERROR, "out_size %zu < %u\n", out_size, len);
+ return -EINVAL;
+ }
+
+ memset(out, 0, len);
+
+ switch (pi->codec) {
+ case CODEC_ULAW:
+ case CODEC_ALAW:
+ break;
+ case CODEC_GSM_FR:
+ out[0] = (out[0] & 0x0f) | 0xD0; /* mask in first four bit for FR */
+ break;
+ case CODEC_GSM_EFR:
+ out[0] = (out[0] & 0x0f) | 0xC0; /* mask in first four bit for EFR */
+ break;
+ case CODEC_GSM_HR:
+ break;
+ case CODEC_AMR_4_75:
+ out[0] = 0 << 4;
+ out[1] = 0 << 3;
+ break;
+ case CODEC_AMR_5_15:
+ out[0] = 1 << 4;
+ out[1] = 1 << 3;
+ break;
+ case CODEC_AMR_5_90:
+ out[0] = 2 << 4;
+ out[1] = 2 << 3;
+ break;
+ case CODEC_AMR_6_70:
+ out[0] = 3 << 4;
+ out[1] = 3 << 3;
+ break;
+ case CODEC_AMR_7_40:
+ out[0] = 4 << 4;
+ out[1] = 4 << 3;
+ break;
+ case CODEC_AMR_7_95:
+ out[0] = 5 << 4;
+ out[1] = 5 << 3;
+ break;
+ case CODEC_AMR_10_2:
+ out[0] = 6 << 4;
+ out[1] = 6 << 3;
+ break;
+ case CODEC_AMR_12_2:
+ out[0] = 7 << 4;
+ out[1] = 7 << 3;
+ break;
+ case CODEC_AMR_SID:
+ out[0] = 2 << 4; /* CMR: 5.90 */
+ out[0] = 8 << 3;
+ break;
+ default:
+ OSMO_ASSERT(0);
+ }
+
+ return len;
+}
+
+
+static struct rtp_provider static_provider = {
+ .name = "static",
+ .rtp_gen = &rtp_gen_static,
+};
+
+static void __attribute__((constructor)) rtp_provider_static_constr(void)
+{
+ rtp_provider_register(&static_provider);
+}
diff --git a/rtpsource/rtpsource.c b/rtpsource/rtpsource.c
index 569d962..3087262 100644
--- a/rtpsource/rtpsource.c
+++ b/rtpsource/rtpsource.c
@@ -48,6 +48,7 @@
#include <osmocom/trau/osmo_ortp.h>
#include "internal.h"
+#include "rtp_provider.h"
/* find a connection based on its CNAME */
@@ -64,13 +65,18 @@
/* create a new RTP connection for given CNAME; includes binding of local RTP port */
struct rtp_connection *create_connection(struct rtpsource_state *rss, const char *cname)
{
+ const struct rtp_provider *rtp_prov;
struct rtp_connection *conn;
+ enum codec_type codec = CODEC_GSM_FR; // TODO: configurable
const char *host;
int port;
int rc;
OSMO_ASSERT(!find_connection_by_cname(rss, cname));
+ rtp_prov = rtp_provider_find("static"); // TODO: configurable
+ OSMO_ASSERT(rtp_prov);
+
conn = talloc_zero(rss, struct rtp_connection);
OSMO_ASSERT(conn);
conn->cname = talloc_strdup(conn, cname);
@@ -90,6 +96,9 @@
osmo_rtp_set_source_desc(conn->rtp_sock, conn->cname, "rtpsource", NULL, NULL,
NULL, "osmo-rtpsource", NULL);
+ conn->rtp_prov_inst = rtp_provider_instance_alloc(conn, rtp_prov, codec);
+ OSMO_ASSERT(conn->rtp_prov_inst);
+
llist_add_tail(&conn->list, &rss->connections);
CLOGP(conn, DMAIN, LOGL_INFO, "Created RTP connection; local=%s:%u\n",
@@ -156,12 +165,11 @@
/* iterate over all RTP connections and send one frame each */
llist_for_each_entry(conn, &rss->connections, list) {
- int i;
- /* TODO: have different sources (file+name, ...) */
- uint8_t payload[33];
- memset(payload, 0, sizeof(payload));
- payload[0] = (payload[0] & 0x0f) | 0xD0; /* mask in first four bit for FR */
- osmo_rtp_send_frame_ext(conn->rtp_sock, payload, sizeof(payload), 160, false);
+ uint8_t payload[256];
+ int i, len;
+
+ len = rtp_provider_instance_gen_frame(conn->rtp_prov_inst, payload, sizeof(payload));
+ osmo_rtp_send_frame_ext(conn->rtp_sock, payload, len, 160, false);
/* make sure RTP clock advances correctly, even if we missed transmit of some */
for (i = 1; i < expire_count; i++)
osmo_rtp_skipped_frame(conn->rtp_sock, 160);
--
To view, visit https://gerrit.osmocom.org/c/mncc-python/+/17978
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: mncc-python
Gerrit-Branch: master
Gerrit-Change-Id: Iad98e1753fef1927c0e8a7493372141372a38224
Gerrit-Change-Number: 17978
Gerrit-PatchSet: 2
Gerrit-Owner: osmith <osmith at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: osmith <osmith at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200501/40872b1f/attachment.htm>