diff options
Diffstat (limited to 'pjmedia/src')
-rw-r--r-- | pjmedia/src/pjmedia/endpoint.c | 39 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/errno.c | 1 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/sdp.c | 48 |
3 files changed, 88 insertions, 0 deletions
diff --git a/pjmedia/src/pjmedia/endpoint.c b/pjmedia/src/pjmedia/endpoint.c index 535e0c5c..b9ebe69a 100644 --- a/pjmedia/src/pjmedia/endpoint.c +++ b/pjmedia/src/pjmedia/endpoint.c @@ -372,6 +372,7 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_audio_sdp(pjmedia_endpt *endpt, pjmedia_sdp_media *m; pjmedia_sdp_attr *attr; unsigned i; + unsigned max_bitrate = 0; pj_status_t status; PJ_UNUSED_ARG(options); @@ -493,6 +494,10 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_audio_sdp(pjmedia_endpt *endpt, attr->value = pj_strdup3(pool, buf); m->attr[m->attr_count++] = attr; } + + /* Find maximum bitrate in this media */ + if (max_bitrate < codec_param.info.max_bps) + max_bitrate = codec_param.info.max_bps; } #if defined(PJMEDIA_RTP_PT_TELEPHONE_EVENTS) && \ @@ -519,6 +524,19 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_audio_sdp(pjmedia_endpt *endpt, } #endif + /* Put bandwidth info in media level using bandwidth modifier "TIAS" + * (RFC3890). + */ + if (max_bitrate) { + const pj_str_t STR_BANDW_MODIFIER = { "TIAS", 4 }; + pjmedia_sdp_bandw *b; + + b = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_bandw); + b->modifier = STR_BANDW_MODIFIER; + b->value = max_bitrate; + m->bandw[m->bandw_count++] = b; + } + *p_m = m; return PJ_SUCCESS; } @@ -541,6 +559,7 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_video_sdp(pjmedia_endpt *endpt, unsigned codec_prio[PJMEDIA_VID_CODEC_MGR_MAX_CODECS]; pjmedia_sdp_attr *attr; unsigned cnt, i; + unsigned max_bitrate = 0; pj_status_t status; PJ_UNUSED_ARG(options); @@ -568,6 +587,7 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_video_sdp(pjmedia_endpt *endpt, pjmedia_sdp_rtpmap rtpmap; pjmedia_vid_codec_param codec_param; pj_str_t *fmt; + pjmedia_video_format_detail *vfd; pj_bzero(&rtpmap, sizeof(rtpmap)); @@ -660,6 +680,25 @@ PJ_DEF(pj_status_t) pjmedia_endpt_create_video_sdp(pjmedia_endpt *endpt, attr->value = pj_strdup3(pool, buf); m->attr[m->attr_count++] = attr; } + + /* Find maximum bitrate in this media */ + vfd = pjmedia_format_get_video_format_detail(&codec_param.enc_fmt, + PJ_TRUE); + if (vfd && max_bitrate < vfd->max_bps) + max_bitrate = vfd->max_bps; + } + + /* Put bandwidth info in media level using bandwidth modifier "TIAS" + * (RFC3890). + */ + if (max_bitrate) { + const pj_str_t STR_BANDW_MODIFIER = { "TIAS", 4 }; + pjmedia_sdp_bandw *b; + + b = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_bandw); + b->modifier = STR_BANDW_MODIFIER; + b->value = max_bitrate; + m->bandw[m->bandw_count++] = b; } *p_m = m; diff --git a/pjmedia/src/pjmedia/errno.c b/pjmedia/src/pjmedia/errno.c index 788f7431..7a8538eb 100644 --- a/pjmedia/src/pjmedia/errno.c +++ b/pjmedia/src/pjmedia/errno.c @@ -66,6 +66,7 @@ static const struct PJ_BUILD_ERR( PJMEDIA_SDP_EINFMTP, "Invalid SDP fmtp attribute" ), PJ_BUILD_ERR( PJMEDIA_SDP_EINRTCP, "Invalid SDP rtcp attribyte" ), PJ_BUILD_ERR( PJMEDIA_SDP_EINPROTO, "Invalid SDP media transport protocol" ), + PJ_BUILD_ERR( PJMEDIA_SDP_EINBANDW, "Invalid SDP bandwidth info line" ), /* SDP negotiator errors. */ PJ_BUILD_ERR( PJMEDIA_SDPNEG_EINSTATE, "Invalid SDP negotiator state for operation" ), diff --git a/pjmedia/src/pjmedia/sdp.c b/pjmedia/src/pjmedia/sdp.c index 417a3dfe..629500c7 100644 --- a/pjmedia/src/pjmedia/sdp.c +++ b/pjmedia/src/pjmedia/sdp.c @@ -59,6 +59,8 @@ static void parse_generic_line(pj_scanner *scanner, pj_str_t *str, parse_context *ctx); static void parse_connection_info(pj_scanner *scanner, pjmedia_sdp_conn *conn, parse_context *ctx); +static void parse_bandwidth_info(pj_scanner *scanner, pjmedia_sdp_bandw *bandw, + parse_context *ctx); static pjmedia_sdp_attr *parse_attr(pj_pool_t *pool, pj_scanner *scanner, parse_context *ctx); static void parse_media(pj_scanner *scanner, pjmedia_sdp_media *med, @@ -810,6 +812,14 @@ static int print_session(const pjmedia_sdp_session *ses, p += printed; } + /* print optional bandwidth info. */ + for (i=0; i<ses->bandw_count; ++i) { + printed = print_bandw(ses->bandw[i], p, end-p); + if (printed < 1) { + return -1; + } + p += printed; + } /* Time */ if ((end-p) < 24) { @@ -991,6 +1001,28 @@ static void parse_connection_info(pj_scanner *scanner, pjmedia_sdp_conn *conn, pj_scan_skip_line(scanner); } +static void parse_bandwidth_info(pj_scanner *scanner, pjmedia_sdp_bandw *bandw, + parse_context *ctx) +{ + pj_str_t str; + + ctx->last_error = PJMEDIA_SDP_EINBANDW; + + /* b= */ + pj_scan_advance_n(scanner, 2, SKIP_WS); + + /* modifier */ + pj_scan_get_until_ch(scanner, ':', &bandw->modifier); + pj_scan_get_char(scanner); + + /* value */ + pj_scan_get_until_chr(scanner, " \t\r\n", &str); + bandw->value = pj_strtoul(&str); + + /* We've got what we're looking for, skip anything until newline */ + pj_scan_skip_line(scanner); +} + static void parse_media(pj_scanner *scanner, pjmedia_sdp_media *med, parse_context *ctx) { @@ -1180,6 +1212,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_parse( pj_pool_t *pool, pjmedia_sdp_media *media = NULL; pjmedia_sdp_attr *attr; pjmedia_sdp_conn *conn; + pjmedia_sdp_bandw *bandw; pj_str_t dummy; int cur_name = 254; parse_context ctx; @@ -1253,6 +1286,15 @@ PJ_DEF(pj_status_t) pjmedia_sdp_parse( pj_pool_t *pool, pj_scan_get_char(&scanner); } break; + case 'b': + bandw = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_bandw); + parse_bandwidth_info(&scanner, bandw, &ctx); + if (media) { + media->bandw[media->bandw_count++] = bandw; + } else { + session->bandw[session->bandw_count++] = bandw; + } + break; default: if (cur_name >= 'a' && cur_name <= 'z') parse_generic_line(&scanner, &dummy, &ctx); @@ -1332,6 +1374,12 @@ PJ_DEF(pjmedia_sdp_session*) pjmedia_sdp_session_clone( pj_pool_t *pool, PJ_ASSERT_RETURN(sess->conn != NULL, NULL); } + /* Duplicate bandwidth info */ + sess->bandw_count = rhs->bandw_count; + for (i=0; i<rhs->bandw_count; ++i) { + sess->bandw[i] = pjmedia_sdp_bandw_clone(pool, rhs->bandw[i]); + } + /* Clone time line. */ sess->time.start = rhs->time.start; sess->time.stop = rhs->time.stop; |