<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>