aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <axilirator@gmail.com>2018-07-09 20:09:50 +0700
committerVadim Yanitskiy <axilirator@gmail.com>2018-07-09 22:16:45 +0700
commit89c1082b3d500e20346da8149e3a668b25495f11 (patch)
treecde53e9ead7bd480873933f27c2dd65207ab7c17
parent62717b6375dfcc39cdb3f70f9ca7127074009c73 (diff)
Make RTP payload type configurable
For a long time the RTP payload type was hard-coded for outgoing frames. The problem is that according to RFC 3551 only GSM FR has a static payload type value (see table 4, value 3). For other codecs the payload type may be negotiated between the both sides dynamically (i.e. in range 96-127). Let's allow a binary/API user to configure this manually. Change-Id: Ia07ed4e13b4a70c8bb4181564a8190861fd269da Closes: OS#2482
-rw-r--r--include/osmocom/gapk/procqueue.h6
-rw-r--r--src/app_osmo_gapk.c37
-rw-r--r--src/pq_rtp.c35
-rw-r--r--tests/io/pq_rtp_test.c4
4 files changed, 64 insertions, 18 deletions
diff --git a/include/osmocom/gapk/procqueue.h b/include/osmocom/gapk/procqueue.h
index ac9253b..82c1cf9 100644
--- a/include/osmocom/gapk/procqueue.h
+++ b/include/osmocom/gapk/procqueue.h
@@ -89,8 +89,10 @@ int osmo_gapk_pq_queue_file_input(struct osmo_gapk_pq *pq, FILE *src, unsigned i
int osmo_gapk_pq_queue_file_output(struct osmo_gapk_pq *pq, FILE *dst, unsigned int block_len);
/* RTP */
-int osmo_gapk_pq_queue_rtp_input(struct osmo_gapk_pq *pq, int rtp_fd, unsigned int block_len);
-int osmo_gapk_pq_queue_rtp_output(struct osmo_gapk_pq *pq, int rtp_fd, unsigned int block_len);
+int osmo_gapk_pq_queue_rtp_input(struct osmo_gapk_pq *pq, int rtp_fd,
+ unsigned int block_len, uint8_t pt);
+int osmo_gapk_pq_queue_rtp_output(struct osmo_gapk_pq *pq, int rtp_fd,
+ unsigned int block_len, uint8_t pt);
/* ALSA */
int osmo_gapk_pq_queue_alsa_input(struct osmo_gapk_pq *pq, const char *hwdev, unsigned int blk_len);
diff --git a/src/app_osmo_gapk.c b/src/app_osmo_gapk.c
index a4b93ef..91647ee 100644
--- a/src/app_osmo_gapk.c
+++ b/src/app_osmo_gapk.c
@@ -64,6 +64,9 @@ struct gapk_options
const char *alsa_out;
const struct osmo_gapk_format_desc *fmt_out;
+ /* RTP payload type */
+ uint8_t rtp_pt_in, rtp_pt_out;
+
int benchmark;
int verbose;
};
@@ -133,6 +136,8 @@ print_help(char *progname)
#endif
fprintf(stdout, " -f, --input-format=FMT\tInput format (see below)\n");
fprintf(stdout, " -g, --output-format=FMT\tOutput format (see below)\n");
+ fprintf(stdout, " -p --rtp-pt-in=TYPE\t\tRTP payload type for incoming frames\n");
+ fprintf(stdout, " -P --rtp-pt-out=TYPE\t\tRTP payload type for outgoing frames\n");
fprintf(stdout, " -b, --enable-benchmark\tEnable codec benchmarking\n");
fprintf(stdout, " -v, --verbose\t\t\tEnable debug messages\n");
fprintf(stdout, "\n");
@@ -203,11 +208,13 @@ parse_options(struct gapk_state *state, int argc, char *argv[])
#endif
{"input-format", 1, 0, 'f'},
{"output-format", 1, 0, 'g'},
+ {"rtp-pt-in", 1, 0, 'p'},
+ {"rtp-pt-out", 1, 0, 'P'},
{"enable-benchmark", 0, 0, 'b'},
{"verbose", 0, 0, 'v'},
{"help", 0, 0, 'h'},
};
- const char *short_options = "i:o:I:O:f:g:bvh"
+ const char *short_options = "i:o:I:O:f:g:p:P:bvh"
#ifdef HAVE_ALSA
"a:A:"
#endif
@@ -218,6 +225,10 @@ parse_options(struct gapk_state *state, int argc, char *argv[])
/* Set some defaults */
memset(opt, 0x00, sizeof(*opt));
+ /* Default RTP payload type (GSM FR, see RFC 3551) */
+ opt->rtp_pt_in = 3;
+ opt->rtp_pt_out = 3;
+
/* Parse */
while (1) {
int c, rv;
@@ -279,6 +290,24 @@ parse_options(struct gapk_state *state, int argc, char *argv[])
}
break;
+ case 'p':
+ rv = atoi(optarg);
+ if (rv < 0 || rv > 0xff) {
+ LOGP(DAPP, LOGL_ERROR, "Invalid RTP payload type: %d\n", rv);
+ return -EINVAL;
+ }
+ opt->rtp_pt_in = rv;
+ break;
+
+ case 'P':
+ rv = atoi(optarg);
+ if (rv < 0 || rv > 0xff) {
+ LOGP(DAPP, LOGL_ERROR, "Invalid RTP payload type: %d\n", rv);
+ return -EINVAL;
+ }
+ opt->rtp_pt_out = rv;
+ break;
+
case 'b':
opt->benchmark = 1;
break;
@@ -540,7 +569,8 @@ make_processing_chain(struct gapk_state *gs)
if (gs->in.file.fh)
osmo_gapk_pq_queue_file_input(gs->pq, gs->in.file.fh, fmt_in->frame_len);
else if (gs->in.rtp.fd != -1)
- osmo_gapk_pq_queue_rtp_input(gs->pq, gs->in.rtp.fd, fmt_in->frame_len);
+ osmo_gapk_pq_queue_rtp_input(gs->pq, gs->in.rtp.fd,
+ fmt_in->frame_len, gs->opts.rtp_pt_in);
#ifdef HAVE_ALSA
else if (gs->opts.alsa_in)
osmo_gapk_pq_queue_alsa_input(gs->pq, gs->opts.alsa_in, fmt_in->frame_len);
@@ -618,7 +648,8 @@ make_processing_chain(struct gapk_state *gs)
if (gs->out.file.fh)
osmo_gapk_pq_queue_file_output(gs->pq, gs->out.file.fh, fmt_out->frame_len);
else if (gs->out.rtp.fd != -1)
- osmo_gapk_pq_queue_rtp_output(gs->pq, gs->out.rtp.fd, fmt_out->frame_len);
+ osmo_gapk_pq_queue_rtp_output(gs->pq, gs->out.rtp.fd,
+ fmt_out->frame_len, gs->opts.rtp_pt_out);
#ifdef HAVE_ALSA
else if (gs->opts.alsa_out)
osmo_gapk_pq_queue_alsa_output(gs->pq, gs->opts.alsa_out, fmt_out->frame_len);
diff --git a/src/pq_rtp.c b/src/pq_rtp.c
index a50013a..81eeb19 100644
--- a/src/pq_rtp.c
+++ b/src/pq_rtp.c
@@ -70,8 +70,6 @@ struct rtp_x_hdr {
#define RTP_VERSION 2
-#define RTP_PT_GSM_FULL 3
-
struct pq_state_rtp {
int fd;
int blk_len;
@@ -193,7 +191,8 @@ pq_cb_rtp_exit(void *_state)
}
static int
-pq_queue_rtp_op(struct osmo_gapk_pq *pq, int udp_fd, unsigned int blk_len, int in_out_n)
+pq_queue_rtp_op(struct osmo_gapk_pq *pq, int udp_fd,
+ unsigned int blk_len, int in_out_n, uint8_t pt)
{
struct osmo_gapk_pq_item *item;
struct pq_state_rtp *state;
@@ -210,12 +209,20 @@ pq_queue_rtp_op(struct osmo_gapk_pq *pq, int udp_fd, unsigned int blk_len, int i
* per RTP frame */
state->duration = 160;
+ /**
+ * RTP payload type according to RFC 3551,
+ * section "6. Payload Type Definitions".
+ *
+ * Only GSM FR has a static payload type value (see table 4).
+ * For other codecs the payload type may be negotiated
+ * between the both sides dynamically (i.e. in range 96-127).
+ */
+ state->payload_type = pt;
+
if (in_out_n == 0) {
state->ssrc = rand();
state->sequence = random();
state->timestamp = random();
- /* FIXME: other payload types!! */
- state->payload_type = RTP_PT_GSM_FULL;
}
item = osmo_gapk_pq_add_item(pq);
@@ -248,24 +255,30 @@ pq_queue_rtp_op(struct osmo_gapk_pq *pq, int udp_fd, unsigned int blk_len, int i
* This typically only makes sense as first item in the queue
* \param pq Processing Queue to add this RTP input to
* \param[in] udp_fd UDP file descriptor for the RTP input
- * \param[in] blk_len Block Length to read from RTP */
+ * \param[in] blk_len Block Length to read from RTP
+ * \param[in] pt Payload type according to RFC 3551
+ */
int
-osmo_gapk_pq_queue_rtp_input(struct osmo_gapk_pq *pq, int udp_fd, unsigned int blk_len)
+osmo_gapk_pq_queue_rtp_input(struct osmo_gapk_pq *pq, int udp_fd,
+ unsigned int blk_len, uint8_t pt)
{
LOGPGAPK(LOGL_DEBUG, "PQ '%s': Adding RTP input (blk_len=%u)\n",
pq->name, blk_len);
- return pq_queue_rtp_op(pq, udp_fd, blk_len, 1);
+ return pq_queue_rtp_op(pq, udp_fd, blk_len, 1, pt);
}
/*! Add RTP output to processing queue.
* This typically only makes sense as last item in the queue
* \param pq Processing Queue to add this RTP output to
* \param[in] udp_fd UDP file descriptor for the RTP output
- * \param[in] blk_len Block Length to read from RTP */
+ * \param[in] blk_len Block Length to read from RTP
+ * \param[in] pt Payload type according to RFC 3551
+ */
int
-osmo_gapk_pq_queue_rtp_output(struct osmo_gapk_pq *pq, int udp_fd, unsigned int blk_len)
+osmo_gapk_pq_queue_rtp_output(struct osmo_gapk_pq *pq, int udp_fd,
+ unsigned int blk_len, uint8_t pt)
{
LOGPGAPK(LOGL_DEBUG, "PQ '%s': Adding RTP output (blk_len=%u)\n",
pq->name, blk_len);
- return pq_queue_rtp_op(pq, udp_fd, blk_len, 0);
+ return pq_queue_rtp_op(pq, udp_fd, blk_len, 0, pt);
}
diff --git a/tests/io/pq_rtp_test.c b/tests/io/pq_rtp_test.c
index 2c1bd41..76f59d2 100644
--- a/tests/io/pq_rtp_test.c
+++ b/tests/io/pq_rtp_test.c
@@ -173,7 +173,7 @@ static int init_gen_queue(struct osmo_gapk_pq *pq,
}
/* Init an RTP sink */
- rc = osmo_gapk_pq_queue_rtp_output(pq, state->rtp_dst_fd, payload_len);
+ rc = osmo_gapk_pq_queue_rtp_output(pq, state->rtp_dst_fd, payload_len, 0x00);
if (rc) {
printf("Could not init an RTP sink\n");
return rc;
@@ -210,7 +210,7 @@ static int init_chk_queue(struct osmo_gapk_pq *pq,
}
/* Init an RTP source on any available port */
- rc = osmo_gapk_pq_queue_rtp_input(pq, state->rtp_src_fd, payload_len);
+ rc = osmo_gapk_pq_queue_rtp_input(pq, state->rtp_src_fd, payload_len, 0x00);
if (rc) {
printf("Could not init an RTP sink\n");
return rc;