<p>Vadim Yanitskiy <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/9928">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
Harald Welte: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Make RTP payload type configurable<br><br>For a long time the RTP payload type was hard-coded for outgoing<br>frames. The problem is that according to RFC 3551 only GSM FR has<br>a static payload type value (see table 4, value 3). For other<br>codecs the payload type may be negotiated between the both<br>sides dynamically (i.e. in range 96-127).<br><br>Let's allow a binary/API user to configure this manually.<br><br>Change-Id: Ia07ed4e13b4a70c8bb4181564a8190861fd269da<br>Closes: OS#2482<br>---<br>M include/osmocom/gapk/procqueue.h<br>M src/app_osmo_gapk.c<br>M src/pq_rtp.c<br>M tests/io/pq_rtp_test.c<br>4 files changed, 64 insertions(+), 18 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/gapk/procqueue.h b/include/osmocom/gapk/procqueue.h</span><br><span>index ac9253b..82c1cf9 100644</span><br><span>--- a/include/osmocom/gapk/procqueue.h</span><br><span>+++ b/include/osmocom/gapk/procqueue.h</span><br><span>@@ -89,8 +89,10 @@</span><br><span> int osmo_gapk_pq_queue_file_output(struct osmo_gapk_pq *pq, FILE *dst, unsigned int block_len);</span><br><span> </span><br><span> /* RTP */</span><br><span style="color: hsl(0, 100%, 40%);">-int osmo_gapk_pq_queue_rtp_input(struct osmo_gapk_pq *pq, int rtp_fd, unsigned int block_len);</span><br><span style="color: hsl(0, 100%, 40%);">-int osmo_gapk_pq_queue_rtp_output(struct osmo_gapk_pq *pq, int rtp_fd, unsigned int block_len);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_gapk_pq_queue_rtp_input(struct osmo_gapk_pq *pq, int rtp_fd,</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int block_len, uint8_t pt);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_gapk_pq_queue_rtp_output(struct osmo_gapk_pq *pq, int rtp_fd,</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int block_len, uint8_t pt);</span><br><span> </span><br><span> /* ALSA */</span><br><span> int osmo_gapk_pq_queue_alsa_input(struct osmo_gapk_pq *pq, const char *hwdev, unsigned int blk_len);</span><br><span>diff --git a/src/app_osmo_gapk.c b/src/app_osmo_gapk.c</span><br><span>index a4b93ef..91647ee 100644</span><br><span>--- a/src/app_osmo_gapk.c</span><br><span>+++ b/src/app_osmo_gapk.c</span><br><span>@@ -64,6 +64,9 @@</span><br><span> const char *alsa_out;</span><br><span> const struct osmo_gapk_format_desc *fmt_out;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* RTP payload type */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t rtp_pt_in, rtp_pt_out;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int benchmark;</span><br><span> int verbose;</span><br><span> };</span><br><span>@@ -133,6 +136,8 @@</span><br><span> #endif</span><br><span> fprintf(stdout, " -f, --input-format=FMT\tInput format (see below)\n");</span><br><span> fprintf(stdout, " -g, --output-format=FMT\tOutput format (see below)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stdout, " -p --rtp-pt-in=TYPE\t\tRTP payload type for incoming frames\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stdout, " -P --rtp-pt-out=TYPE\t\tRTP payload type for outgoing frames\n");</span><br><span> fprintf(stdout, " -b, --enable-benchmark\tEnable codec benchmarking\n");</span><br><span> fprintf(stdout, " -v, --verbose\t\t\tEnable debug messages\n");</span><br><span> fprintf(stdout, "\n");</span><br><span>@@ -203,11 +208,13 @@</span><br><span> #endif</span><br><span> {"input-format", 1, 0, 'f'},</span><br><span> {"output-format", 1, 0, 'g'},</span><br><span style="color: hsl(120, 100%, 40%);">+ {"rtp-pt-in", 1, 0, 'p'},</span><br><span style="color: hsl(120, 100%, 40%);">+ {"rtp-pt-out", 1, 0, 'P'},</span><br><span> {"enable-benchmark", 0, 0, 'b'},</span><br><span> {"verbose", 0, 0, 'v'},</span><br><span> {"help", 0, 0, 'h'},</span><br><span> };</span><br><span style="color: hsl(0, 100%, 40%);">- const char *short_options = "i:o:I:O:f:g:bvh"</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *short_options = "i:o:I:O:f:g:p:P:bvh"</span><br><span> #ifdef HAVE_ALSA</span><br><span> "a:A:"</span><br><span> #endif</span><br><span>@@ -218,6 +225,10 @@</span><br><span> /* Set some defaults */</span><br><span> memset(opt, 0x00, sizeof(*opt));</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Default RTP payload type (GSM FR, see RFC 3551) */</span><br><span style="color: hsl(120, 100%, 40%);">+ opt->rtp_pt_in = 3;</span><br><span style="color: hsl(120, 100%, 40%);">+ opt->rtp_pt_out = 3;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Parse */</span><br><span> while (1) {</span><br><span> int c, rv;</span><br><span>@@ -279,6 +290,24 @@</span><br><span> }</span><br><span> break;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ case 'p':</span><br><span style="color: hsl(120, 100%, 40%);">+ rv = atoi(optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rv < 0 || rv > 0xff) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DAPP, LOGL_ERROR, "Invalid RTP payload type: %d\n", rv);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ opt->rtp_pt_in = rv;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case 'P':</span><br><span style="color: hsl(120, 100%, 40%);">+ rv = atoi(optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rv < 0 || rv > 0xff) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DAPP, LOGL_ERROR, "Invalid RTP payload type: %d\n", rv);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ opt->rtp_pt_out = rv;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> case 'b':</span><br><span> opt->benchmark = 1;</span><br><span> break;</span><br><span>@@ -540,7 +569,8 @@</span><br><span> if (gs->in.file.fh)</span><br><span> osmo_gapk_pq_queue_file_input(gs->pq, gs->in.file.fh, fmt_in->frame_len);</span><br><span> else if (gs->in.rtp.fd != -1)</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_gapk_pq_queue_rtp_input(gs->pq, gs->in.rtp.fd, fmt_in->frame_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_gapk_pq_queue_rtp_input(gs->pq, gs->in.rtp.fd,</span><br><span style="color: hsl(120, 100%, 40%);">+ fmt_in->frame_len, gs->opts.rtp_pt_in);</span><br><span> #ifdef HAVE_ALSA</span><br><span> else if (gs->opts.alsa_in)</span><br><span> osmo_gapk_pq_queue_alsa_input(gs->pq, gs->opts.alsa_in, fmt_in->frame_len);</span><br><span>@@ -618,7 +648,8 @@</span><br><span> if (gs->out.file.fh)</span><br><span> osmo_gapk_pq_queue_file_output(gs->pq, gs->out.file.fh, fmt_out->frame_len);</span><br><span> else if (gs->out.rtp.fd != -1)</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_gapk_pq_queue_rtp_output(gs->pq, gs->out.rtp.fd, fmt_out->frame_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_gapk_pq_queue_rtp_output(gs->pq, gs->out.rtp.fd,</span><br><span style="color: hsl(120, 100%, 40%);">+ fmt_out->frame_len, gs->opts.rtp_pt_out);</span><br><span> #ifdef HAVE_ALSA</span><br><span> else if (gs->opts.alsa_out)</span><br><span> osmo_gapk_pq_queue_alsa_output(gs->pq, gs->opts.alsa_out, fmt_out->frame_len);</span><br><span>diff --git a/src/pq_rtp.c b/src/pq_rtp.c</span><br><span>index a50013a..81eeb19 100644</span><br><span>--- a/src/pq_rtp.c</span><br><span>+++ b/src/pq_rtp.c</span><br><span>@@ -70,8 +70,6 @@</span><br><span> </span><br><span> #define RTP_VERSION 2</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#define RTP_PT_GSM_FULL 3</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> struct pq_state_rtp {</span><br><span> int fd;</span><br><span> int blk_len;</span><br><span>@@ -193,7 +191,8 @@</span><br><span> }</span><br><span> </span><br><span> static int</span><br><span style="color: hsl(0, 100%, 40%);">-pq_queue_rtp_op(struct osmo_gapk_pq *pq, int udp_fd, unsigned int blk_len, int in_out_n)</span><br><span style="color: hsl(120, 100%, 40%);">+pq_queue_rtp_op(struct osmo_gapk_pq *pq, int udp_fd,</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int blk_len, int in_out_n, uint8_t pt)</span><br><span> {</span><br><span> struct osmo_gapk_pq_item *item;</span><br><span> struct pq_state_rtp *state;</span><br><span>@@ -210,12 +209,20 @@</span><br><span> * per RTP frame */</span><br><span> state->duration = 160;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /**</span><br><span style="color: hsl(120, 100%, 40%);">+ * RTP payload type according to RFC 3551,</span><br><span style="color: hsl(120, 100%, 40%);">+ * section "6. Payload Type Definitions".</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Only GSM FR has a static payload type value (see table 4).</span><br><span style="color: hsl(120, 100%, 40%);">+ * For other codecs the payload type may be negotiated</span><br><span style="color: hsl(120, 100%, 40%);">+ * between the both sides dynamically (i.e. in range 96-127).</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ state->payload_type = pt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if (in_out_n == 0) {</span><br><span> state->ssrc = rand();</span><br><span> state->sequence = random();</span><br><span> state->timestamp = random();</span><br><span style="color: hsl(0, 100%, 40%);">- /* FIXME: other payload types!! */</span><br><span style="color: hsl(0, 100%, 40%);">- state->payload_type = RTP_PT_GSM_FULL;</span><br><span> }</span><br><span> </span><br><span> item = osmo_gapk_pq_add_item(pq);</span><br><span>@@ -248,24 +255,30 @@</span><br><span> * This typically only makes sense as first item in the queue</span><br><span> * \param pq Processing Queue to add this RTP input to</span><br><span> * \param[in] udp_fd UDP file descriptor for the RTP input</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] blk_len Block Length to read from RTP */</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] blk_len Block Length to read from RTP</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] pt Payload type according to RFC 3551</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span> int</span><br><span style="color: hsl(0, 100%, 40%);">-osmo_gapk_pq_queue_rtp_input(struct osmo_gapk_pq *pq, int udp_fd, unsigned int blk_len)</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_gapk_pq_queue_rtp_input(struct osmo_gapk_pq *pq, int udp_fd,</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int blk_len, uint8_t pt)</span><br><span> {</span><br><span> LOGPGAPK(LOGL_DEBUG, "PQ '%s': Adding RTP input (blk_len=%u)\n",</span><br><span> pq->name, blk_len);</span><br><span style="color: hsl(0, 100%, 40%);">- return pq_queue_rtp_op(pq, udp_fd, blk_len, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ return pq_queue_rtp_op(pq, udp_fd, blk_len, 1, pt);</span><br><span> }</span><br><span> </span><br><span> /*! Add RTP output to processing queue.</span><br><span> * This typically only makes sense as last item in the queue</span><br><span> * \param pq Processing Queue to add this RTP output to</span><br><span> * \param[in] udp_fd UDP file descriptor for the RTP output</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] blk_len Block Length to read from RTP */</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] blk_len Block Length to read from RTP</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] pt Payload type according to RFC 3551</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span> int</span><br><span style="color: hsl(0, 100%, 40%);">-osmo_gapk_pq_queue_rtp_output(struct osmo_gapk_pq *pq, int udp_fd, unsigned int blk_len)</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_gapk_pq_queue_rtp_output(struct osmo_gapk_pq *pq, int udp_fd,</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int blk_len, uint8_t pt)</span><br><span> {</span><br><span> LOGPGAPK(LOGL_DEBUG, "PQ '%s': Adding RTP output (blk_len=%u)\n",</span><br><span> pq->name, blk_len);</span><br><span style="color: hsl(0, 100%, 40%);">- return pq_queue_rtp_op(pq, udp_fd, blk_len, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ return pq_queue_rtp_op(pq, udp_fd, blk_len, 0, pt);</span><br><span> }</span><br><span>diff --git a/tests/io/pq_rtp_test.c b/tests/io/pq_rtp_test.c</span><br><span>index 2c1bd41..76f59d2 100644</span><br><span>--- a/tests/io/pq_rtp_test.c</span><br><span>+++ b/tests/io/pq_rtp_test.c</span><br><span>@@ -173,7 +173,7 @@</span><br><span> }</span><br><span> </span><br><span> /* Init an RTP sink */</span><br><span style="color: hsl(0, 100%, 40%);">- rc = osmo_gapk_pq_queue_rtp_output(pq, state->rtp_dst_fd, payload_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_gapk_pq_queue_rtp_output(pq, state->rtp_dst_fd, payload_len, 0x00);</span><br><span> if (rc) {</span><br><span> printf("Could not init an RTP sink\n");</span><br><span> return rc;</span><br><span>@@ -210,7 +210,7 @@</span><br><span> }</span><br><span> </span><br><span> /* Init an RTP source on any available port */</span><br><span style="color: hsl(0, 100%, 40%);">- rc = osmo_gapk_pq_queue_rtp_input(pq, state->rtp_src_fd, payload_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_gapk_pq_queue_rtp_input(pq, state->rtp_src_fd, payload_len, 0x00);</span><br><span> if (rc) {</span><br><span> printf("Could not init an RTP sink\n");</span><br><span> return rc;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/9928">change 9928</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/9928"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: gapk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ia07ed4e13b4a70c8bb4181564a8190861fd269da </div>
<div style="display:none"> Gerrit-Change-Number: 9928 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: Vadim Yanitskiy <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: Vadim Yanitskiy <axilirator@gmail.com> </div>