Changeset 3945


Ignore:
Timestamp:
Jan 27, 2012 9:12:59 AM (13 years ago)
Author:
nanang
Message:

Re #1244: Added bandwidth info in SDP ("b=" lines) based on codec bitrate settings. Two SDP bandwidth types/modifiers are used: AS in session level & TIAS in media level.

Location:
pjproject/trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/include/pjmedia/errno.h

    r3901 r3945  
    172172 */ 
    173173#define PJMEDIA_SDP_EINPROTO        (PJMEDIA_ERRNO_START+36)    /* 220036 */ 
     174/** 
     175 * @hideinitializer 
     176 * Invalid SDP bandwidth info (b=) line. 
     177 */ 
     178#define PJMEDIA_SDP_EINBANDW        (PJMEDIA_ERRNO_START+37)    /* 220037 */ 
    174179 
    175180 
  • pjproject/trunk/pjmedia/include/pjmedia/sdp.h

    r3664 r3945  
    615615    } origin; 
    616616 
    617     pj_str_t         name;          /**< Subject line (s=)              */ 
    618     pjmedia_sdp_conn *conn;         /**< Connection line (c=)           */ 
     617    pj_str_t           name;        /**< Subject line (s=)              */ 
     618    pjmedia_sdp_conn  *conn;        /**< Connection line (c=)           */ 
     619    unsigned           bandw_count; /**< Number of bandwidth info (b=)  */ 
     620    pjmedia_sdp_bandw *bandw[PJMEDIA_MAX_SDP_BANDW]; 
     621                                    /**< Bandwidth info array (b=)      */ 
    619622     
    620623    /** Session time (t= line)  */ 
  • pjproject/trunk/pjmedia/src/pjmedia/endpoint.c

    r3776 r3945  
    373373    pjmedia_sdp_attr *attr; 
    374374    unsigned i; 
     375    unsigned max_bitrate = 0; 
    375376    pj_status_t status; 
    376377 
     
    494495            m->attr[m->attr_count++] = attr; 
    495496        } 
     497 
     498        /* Find maximum bitrate in this media */ 
     499        if (max_bitrate < codec_param.info.max_bps) 
     500            max_bitrate = codec_param.info.max_bps; 
    496501    } 
    497502 
     
    520525#endif 
    521526 
     527    /* Put bandwidth info in media level using bandwidth modifier "TIAS" 
     528     * (RFC3890). 
     529     */ 
     530    if (max_bitrate) { 
     531        const pj_str_t STR_BANDW_MODIFIER = { "TIAS", 4 }; 
     532        pjmedia_sdp_bandw *b; 
     533             
     534        b = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_bandw); 
     535        b->modifier = STR_BANDW_MODIFIER; 
     536        b->value = max_bitrate; 
     537        m->bandw[m->bandw_count++] = b; 
     538    } 
     539 
    522540    *p_m = m; 
    523541    return PJ_SUCCESS; 
     
    542560    pjmedia_sdp_attr *attr; 
    543561    unsigned cnt, i; 
     562    unsigned max_bitrate = 0; 
    544563    pj_status_t status; 
    545564 
     
    569588        pjmedia_vid_codec_param codec_param; 
    570589        pj_str_t *fmt; 
     590        pjmedia_video_format_detail *vfd; 
    571591 
    572592        pj_bzero(&rtpmap, sizeof(rtpmap)); 
     
    661681            m->attr[m->attr_count++] = attr; 
    662682        } 
     683     
     684        /* Find maximum bitrate in this media */ 
     685        vfd = pjmedia_format_get_video_format_detail(&codec_param.enc_fmt, 
     686                                                     PJ_TRUE); 
     687        if (vfd && max_bitrate < vfd->max_bps) 
     688            max_bitrate = vfd->max_bps; 
     689    } 
     690 
     691    /* Put bandwidth info in media level using bandwidth modifier "TIAS" 
     692     * (RFC3890). 
     693     */ 
     694    if (max_bitrate) { 
     695        const pj_str_t STR_BANDW_MODIFIER = { "TIAS", 4 }; 
     696        pjmedia_sdp_bandw *b; 
     697             
     698        b = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_bandw); 
     699        b->modifier = STR_BANDW_MODIFIER; 
     700        b->value = max_bitrate; 
     701        m->bandw[m->bandw_count++] = b; 
    663702    } 
    664703 
  • pjproject/trunk/pjmedia/src/pjmedia/errno.c

    r3901 r3945  
    6767    PJ_BUILD_ERR( PJMEDIA_SDP_EINRTCP,      "Invalid SDP rtcp attribyte" ), 
    6868    PJ_BUILD_ERR( PJMEDIA_SDP_EINPROTO,     "Invalid SDP media transport protocol" ), 
     69    PJ_BUILD_ERR( PJMEDIA_SDP_EINBANDW,     "Invalid SDP bandwidth info line" ), 
    6970 
    7071    /* SDP negotiator errors. */ 
  • pjproject/trunk/pjmedia/src/pjmedia/sdp.c

    r3553 r3945  
    6060static void parse_connection_info(pj_scanner *scanner, pjmedia_sdp_conn *conn, 
    6161                                  parse_context *ctx); 
     62static void parse_bandwidth_info(pj_scanner *scanner, pjmedia_sdp_bandw *bandw, 
     63                                  parse_context *ctx); 
    6264static pjmedia_sdp_attr *parse_attr(pj_pool_t *pool, pj_scanner *scanner, 
    6365                                    parse_context *ctx); 
     
    811813    } 
    812814 
     815    /* print optional bandwidth info. */ 
     816    for (i=0; i<ses->bandw_count; ++i) { 
     817        printed = print_bandw(ses->bandw[i], p, end-p); 
     818        if (printed < 1) { 
     819            return -1; 
     820        } 
     821        p += printed; 
     822    } 
    813823 
    814824    /* Time */ 
     
    987997    pj_scan_get_until_chr(scanner, "/ \t\r\n", &conn->addr); 
    988998    PJ_TODO(PARSE_SDP_CONN_ADDRESS_SUBFIELDS); 
     999 
     1000    /* We've got what we're looking for, skip anything until newline */ 
     1001    pj_scan_skip_line(scanner); 
     1002} 
     1003 
     1004static void parse_bandwidth_info(pj_scanner *scanner, pjmedia_sdp_bandw *bandw, 
     1005                                  parse_context *ctx) 
     1006{ 
     1007    pj_str_t str; 
     1008 
     1009    ctx->last_error = PJMEDIA_SDP_EINBANDW; 
     1010 
     1011    /* b= */ 
     1012    pj_scan_advance_n(scanner, 2, SKIP_WS); 
     1013 
     1014    /* modifier */ 
     1015    pj_scan_get_until_ch(scanner, ':', &bandw->modifier); 
     1016    pj_scan_get_char(scanner); 
     1017 
     1018    /* value */ 
     1019    pj_scan_get_until_chr(scanner, " \t\r\n", &str); 
     1020    bandw->value = pj_strtoul(&str); 
    9891021 
    9901022    /* We've got what we're looking for, skip anything until newline */ 
     
    11811213    pjmedia_sdp_attr *attr; 
    11821214    pjmedia_sdp_conn *conn; 
     1215    pjmedia_sdp_bandw *bandw; 
    11831216    pj_str_t dummy; 
    11841217    int cur_name = 254; 
     
    12541287                    } 
    12551288                    break; 
     1289                case 'b': 
     1290                    bandw = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_bandw); 
     1291                    parse_bandwidth_info(&scanner, bandw, &ctx); 
     1292                    if (media) { 
     1293                        media->bandw[media->bandw_count++] = bandw; 
     1294                    } else { 
     1295                        session->bandw[session->bandw_count++] = bandw; 
     1296                    } 
     1297                    break; 
    12561298                default: 
    12571299                    if (cur_name >= 'a' && cur_name <= 'z') 
     
    13331375    } 
    13341376 
     1377    /* Duplicate bandwidth info */ 
     1378    sess->bandw_count = rhs->bandw_count; 
     1379    for (i=0; i<rhs->bandw_count; ++i) { 
     1380        sess->bandw[i] = pjmedia_sdp_bandw_clone(pool, rhs->bandw[i]); 
     1381    } 
     1382 
    13351383    /* Clone time line. */ 
    13361384    sess->time.start = rhs->time.start; 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r3938 r3945  
    19391939    pjmedia_sdp_neg_state sdp_neg_state = PJMEDIA_SDP_NEG_STATE_NULL; 
    19401940    unsigned mi; 
     1941    unsigned tot_bandw_tias = 0; 
    19411942    pj_status_t status; 
    19421943 
     
    20122013        pjmedia_sdp_media *m = NULL; 
    20132014        pjmedia_transport_info tpinfo; 
     2015        unsigned i; 
    20142016 
    20152017        if (rem_sdp && mi >= rem_sdp->media_count) { 
     
    21092111            sdp->conn = pjmedia_sdp_conn_clone(pool, m->conn); 
    21102112        } 
     2113 
     2114         
     2115        /* Find media bandwidth info */ 
     2116        for (i = 0; i < m->bandw_count; ++i) { 
     2117            const pj_str_t STR_BANDW_MODIFIER_TIAS = { "TIAS", 4 }; 
     2118            if (!pj_stricmp(&m->bandw[i]->modifier, &STR_BANDW_MODIFIER_TIAS)) 
     2119            { 
     2120                tot_bandw_tias += m->bandw[i]->value; 
     2121                break; 
     2122            } 
     2123        } 
    21112124    } 
    21122125 
     
    21332146        pjmedia_sdp_attr_add(&sdp->attr_count, sdp->attr, a); 
    21342147 
     2148    } 
     2149 
     2150 
     2151    /* Add bandwidth info in session level using bandwidth modifier "AS". */ 
     2152    if (tot_bandw_tias) { 
     2153        unsigned bandw; 
     2154        const pj_str_t STR_BANDW_MODIFIER_AS = { "AS", 2 }; 
     2155        pjmedia_sdp_bandw *b; 
     2156 
     2157        /* AS bandwidth = RTP bitrate + RTCP bitrate. 
     2158         * RTP bitrate  = payload bitrate (total TIAS) + overheads (~16kbps). 
     2159         * RTCP bitrate = est. 5% of RTP bitrate. 
     2160         * Note that AS bandwidth is in kbps. 
     2161         */ 
     2162        bandw = tot_bandw_tias + 16000; 
     2163        bandw += bandw * 5 / 100; 
     2164        b = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_bandw); 
     2165        b->modifier = STR_BANDW_MODIFIER_AS; 
     2166        b->value = bandw / 1000; 
     2167        sdp->bandw[sdp->bandw_count++] = b; 
    21352168    } 
    21362169 
Note: See TracChangeset for help on using the changeset viewer.