mirror of https://gerrit.osmocom.org/gapk
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#2482changes/28/9928/4
parent
62717b6375
commit
89c1082b3d
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
35
src/pq_rtp.c
35
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue