Skip to content

Commit

Permalink
pcaputil: Support parsing decoder options from FMTP input
Browse files Browse the repository at this point in the history
Some codecs need specific flags that are given in the SDP media
description. For example, AMR has octet-align=1.

Instead of adding a separate flag for each codec, allow pcaputil
to accept the fmtp content and parse the attributes from there.

Example:
pcaputil \
  --dst-port=52422 \
  --codec=AMR/8000 \
  --fmtp='mode-set=0,1,2,3,4,5,6,7;octet-align=1' \
  amr.pcap amr.wav
  • Loading branch information
orgads committed Dec 11, 2024
1 parent 85b38f4 commit ac0cefa
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 3 deletions.
15 changes: 15 additions & 0 deletions pjmedia/include/pjmedia/stream_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,21 @@ PJ_DECL(pj_status_t) pjmedia_stream_info_parse_fmtp(pj_pool_t *pool,
pjmedia_codec_fmtp *fmtp);


/**
* This is an internal function for parsing fmtp data from a raw buffer.
*
* @param pool Pool to allocate memory, if pool is NULL, the fmtp
* string pointers will point to the original string.
* @param str The fmtp string to be parsed.
* @param fmtp The format parameter to store the parsing result.
*
* @return PJ_SUCCESS on success.
*/
PJ_DECL(pj_status_t) pjmedia_stream_info_parse_fmtp_data(pj_pool_t *pool,
const pj_str_t *str,
pjmedia_codec_fmtp *fmtp);


PJ_END_DECL


Expand Down
13 changes: 10 additions & 3 deletions pjmedia/src/pjmedia/stream_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_info_parse_fmtp( pj_pool_t *pool,
{
const pjmedia_sdp_attr *attr;
pjmedia_sdp_fmtp sdp_fmtp;
char *p, *p_end, fmt_buf[8];
char fmt_buf[8];
pj_str_t fmt;
pj_status_t status;

Expand All @@ -63,9 +63,16 @@ PJ_DEF(pj_status_t) pjmedia_stream_info_parse_fmtp( pj_pool_t *pool,
if (status != PJ_SUCCESS)
return status;

return pjmedia_stream_info_parse_fmtp_data(pool, &sdp_fmtp.fmt_param, fmtp);
}

PJ_DECL(pj_status_t) pjmedia_stream_info_parse_fmtp_data(pj_pool_t *pool,
const pj_str_t *str,
pjmedia_codec_fmtp *fmtp)
{
/* Prepare parsing */
p = sdp_fmtp.fmt_param.ptr;
p_end = p + sdp_fmtp.fmt_param.slen;
char *p = str->ptr;
char *p_end = p + str->slen;

/* Parse */
while (p < p_end) {
Expand Down
10 changes: 10 additions & 0 deletions pjsip-apps/src/samples/pcaputil.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ static const char *USAGE =
" AES_CM_128_HMAC_SHA1_80 \n"
" AES_CM_128_HMAC_SHA1_32\n"
" --srtp-key=KEY, -k Set the base64 key to decrypt SRTP packets.\n"
" --fmtp=FMTP Set the fmtp input for parsing codec options.\n"
#if PJMEDIA_HAS_OPUS_CODEC
" --opus-ch=CH Opus channel count \n"
" --opus-clock-rate=CR Opus clock rate \n"
Expand Down Expand Up @@ -93,6 +94,7 @@ struct args
pjmedia_aud_dev_index dev_id;
pj_str_t srtp_crypto;
pj_str_t srtp_key;
pj_str_t fmtp;
#if PJMEDIA_HAS_OPUS_CODEC
int opus_clock_rate;
int opus_ch;
Expand Down Expand Up @@ -338,6 +340,9 @@ static void pcap2wav(const struct args *args)
ci = info[0];
}
T( pjmedia_codec_mgr_get_default_param(cmgr, ci, &param) );
if (args->fmtp.slen > 0) {
T( pjmedia_stream_info_parse_fmtp_data(app.pool, &args->fmtp, &param.setting.dec_fmtp) );
}

/* Alloc and init codec */
T( pjmedia_codec_mgr_alloc_codec(cmgr, ci, &app.codec) );
Expand Down Expand Up @@ -465,6 +470,7 @@ int main(int argc, char *argv[])
OPT_DST_PORT,
OPT_CODEC,
OPT_PLAY_DEV_ID,
OPT_FMTP,
#if PJMEDIA_HAS_OPUS_CODEC
OPT_OPUS_CH = 'C',
OPT_OPUS_CLOCK_RATE = 'K',
Expand All @@ -481,6 +487,7 @@ int main(int argc, char *argv[])
{ "dst-port", 1, 0, OPT_DST_PORT },
{ "codec", 1, 0, OPT_CODEC },
{ "play-dev-id", 1, 0, OPT_PLAY_DEV_ID },
{ "fmtp", 1, 0, OPT_FMTP },
#if PJMEDIA_HAS_OPUS_CODEC
{ "opus-ch", 1, 0, OPT_OPUS_CH },
{ "opus-clock-rate", 1, 0, OPT_OPUS_CLOCK_RATE },
Expand Down Expand Up @@ -548,6 +555,9 @@ int main(int argc, char *argv[])
case OPT_PLAY_DEV_ID:
args.dev_id = atoi(pj_optarg);
break;
case OPT_FMTP:
args.fmtp = pj_str(pj_optarg);
break;
#if PJMEDIA_HAS_OPUS_CODEC
case OPT_OPUS_CLOCK_RATE:
args.opus_clock_rate = atoi(pj_optarg);
Expand Down

0 comments on commit ac0cefa

Please sign in to comment.