Ignore:
Timestamp:
Aug 25, 2008 1:58:25 PM (13 years ago)
Author:
nanang
Message:

Ticket #599:

  • Added "dec_fmtp" and "enc_fmtp" fields to pjmedia_codec_param.setting.
  • Codec factory puts its default parameters in "dec_fmtp" field.
  • pjmedia_stream_info_from_sdp() puts the "fmtp" attribute in SDP to pjmedia_codec_param.
  • Special treatment for fmtp "bitrate" parameter (of G722.1) during SDP negotiation
  • Added maxptime field in stream_info.
  • Replaced iLBC's fmtp "mode" implementation to use general fmtp mechanism.
  • Added some test scripts for G722.1 bitrate negotiation.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/session.c

    r2153 r2236  
    6868 
    6969/* 
    70  * Get fmtp mode parameter associated with the codec. 
    71  */ 
    72 static pj_status_t get_fmtp_mode(const pjmedia_sdp_media *m, 
    73                                  const pj_str_t *fmt, 
    74                                  int *p_mode) 
     70 * Parse fmtp for specified format/payload type. 
     71 */ 
     72static void parse_fmtp( pj_pool_t *pool, 
     73                        const pjmedia_sdp_media *m, 
     74                        unsigned pt, 
     75                        pjmedia_codec_fmtp *fmtp) 
    7576{ 
    7677    const pjmedia_sdp_attr *attr; 
    77     pjmedia_sdp_fmtp fmtp; 
    78     const pj_str_t str_mode = { "mode=", 5 }; 
    79     char *pos; 
     78    pjmedia_sdp_fmtp sdp_fmtp; 
     79    char *p, *p_end, fmt_buf[8]; 
     80    pj_str_t fmt; 
     81 
     82    pj_assert(m && fmtp); 
     83 
     84    pj_bzero(fmtp, sizeof(pjmedia_codec_fmtp)); 
    8085 
    8186    /* Get "fmtp" attribute for the format */ 
    82     attr = pjmedia_sdp_media_find_attr2(m, "fmtp", fmt); 
     87    pj_ansi_sprintf(fmt_buf, "%d", pt); 
     88    fmt = pj_str(fmt_buf); 
     89    attr = pjmedia_sdp_media_find_attr2(m, "fmtp", &fmt); 
    8390    if (attr == NULL) 
    84         return -1; 
     91        return; 
    8592 
    8693    /* Parse "fmtp" attribute */ 
    87     if (pjmedia_sdp_attr_get_fmtp(attr, &fmtp) != PJ_SUCCESS) 
    88         return -1; 
    89  
    90     /* Look for "mode=" string in the fmtp */ 
    91     while (fmtp.fmt_param.slen >= str_mode.slen + 1) { 
    92         if (pj_strnicmp(&fmtp.fmt_param, &str_mode, str_mode.slen)==0) { 
    93             /* Found "mode=" string */ 
     94    if (pjmedia_sdp_attr_get_fmtp(attr, &sdp_fmtp) != PJ_SUCCESS) 
     95        return; 
     96 
     97    /* Prepare parsing */ 
     98    p = sdp_fmtp.fmt_param.ptr; 
     99    p_end = p + sdp_fmtp.fmt_param.slen; 
     100 
     101    /* Parse */ 
     102    while (p < p_end) { 
     103        char *token, *start, *end; 
     104 
     105        /* Skip whitespaces */ 
     106        while (p < p_end && (*p == ' ' || *p == '\t')) ++p; 
     107        if (p == p_end) 
    94108            break; 
    95         } 
    96  
    97         fmtp.fmt_param.ptr++; 
    98         fmtp.fmt_param.slen--; 
    99     } 
    100  
    101     if (fmtp.fmt_param.slen < str_mode.slen + 1) { 
    102         /* "mode=" param not found */ 
    103         return -1; 
    104     } 
    105  
    106     /* Get the mode */ 
    107     pos = fmtp.fmt_param.ptr + str_mode.slen; 
    108     *p_mode = 0; 
    109     while (pj_isdigit(*pos)) { 
    110         *p_mode = *p_mode * 10 + (*pos - '0'); 
    111         ++pos; 
    112     } 
    113  
    114     return PJ_SUCCESS; 
     109 
     110        /* Get token */ 
     111        start = p; 
     112        while (p < p_end && *p != ';' && *p != '=') ++p; 
     113        end = p - 1; 
     114 
     115        /* Right trim */ 
     116        while (end >= start && (*end == ' '  || *end == '\t' ||  
     117                                *end == '\r' || *end == '\n' )) 
     118            --end; 
     119 
     120        /* Forward a char after trimming */ 
     121        ++end; 
     122 
     123        /* Store token */ 
     124        if (end > start) { 
     125            token = (char*)pj_pool_alloc(pool, end - start); 
     126            pj_ansi_strncpy(token, start, end - start); 
     127            if (*p == '=') 
     128                /* Got param name */ 
     129                pj_strset(&fmtp->param[fmtp->cnt].name, token, end - start); 
     130            else 
     131                /* Got param value */ 
     132                pj_strset(&fmtp->param[fmtp->cnt++].val, token, end - start); 
     133        } else if (*p != '=') { 
     134            ++fmtp->cnt; 
     135        } 
     136 
     137        /* Next */ 
     138        ++p; 
     139    } 
    115140} 
    116141 
     
    136161    pj_sockaddr local_addr; 
    137162    pjmedia_sdp_rtpmap *rtpmap; 
    138     int local_fmtp_mode = 0, rem_fmtp_mode = 0; 
    139163    unsigned i, pt, fmti; 
    140164    pj_status_t status; 
     
    401425#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG != 0) 
    402426            /* The session info should have the actual clock rate, because  
    403              * this info is used for calculationg buffer size, etc in stream */ 
     427             * this info is used for calculationg buffer size, etc in stream  
     428             */ 
    404429            if (si->fmt.pt == PJMEDIA_RTP_PT_G722) 
    405430                si->fmt.clock_rate = 16000; 
     
    464489        } 
    465490 
    466         /* Get fmtp mode= param in local SDP, if any */ 
    467         get_fmtp_mode(local_m, &local_m->desc.fmt[fmti], &local_fmtp_mode); 
    468  
    469491        /* Determine payload type for outgoing channel, by finding 
    470492         * dynamic payload type in remote SDP that matches the answer. 
     
    494516                si->tx_pt = rpt; 
    495517 
    496                 /* Get fmtp mode param in remote SDP, if any */ 
    497                 get_fmtp_mode(rem_m, &rtpmap->pt, &rem_fmtp_mode); 
    498  
    499518                break; 
    500519            } 
     
    509528    si->param = PJ_POOL_ALLOC_T(pool, pjmedia_codec_param); 
    510529    status = pjmedia_codec_mgr_get_default_param(mgr, &si->fmt, si->param); 
     530 
     531    /* Get remote fmtp for our encoder. */ 
     532    parse_fmtp(pool, rem_m, si->tx_pt, &si->param->setting.enc_fmtp); 
     533 
     534    /* Get local fmtp for our decoder. */ 
     535    parse_fmtp(pool, local_m, si->fmt.pt, &si->param->setting.dec_fmtp); 
     536 
     537    /* Get remote maxptime for our encoder. */ 
     538    attr = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 
     539                                  "maxptime", NULL); 
     540    if (attr) { 
     541        pj_str_t tmp_val = attr->value; 
     542 
     543        pj_strltrim(&tmp_val); 
     544        si->tx_maxptime = pj_strtoul(&tmp_val); 
     545    } 
    511546 
    512547    /* When direction is NONE (it means SDP negotiation has failed) we don't 
     
    520555        return status; 
    521556 
    522     /* Set fmtp mode for both local and remote */ 
    523     if (local_fmtp_mode != 0) 
    524         si->param->setting.dec_fmtp_mode = (pj_int8_t)local_fmtp_mode; 
    525     if (rem_fmtp_mode != 0) 
    526         si->param->setting.enc_fmtp_mode = (pj_int8_t)rem_fmtp_mode; 
    527  
    528557 
    529558    /* Get incomming payload type for telephone-events */ 
Note: See TracChangeset for help on using the changeset viewer.