Changeset 2834


Ignore:
Timestamp:
Jul 15, 2009 5:55:16 PM (15 years ago)
Author:
nanang
Message:

Ticket #919:

  • Added default ilbc mode into codec passthrough setting.
  • Added iLBC mode 'negotiation' in iLBC codec_open().
  • Updated stream_create() to prioritize codec_open(), that may update the codec params, over stream initializations involving codec params.
Location:
pjproject/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/include/pjmedia-codec/passthrough.h

    r2825 r2834  
    5959    pjmedia_format      *fmts;          /**< Encoding formats to be  
    6060                                             enabled.                   */ 
     61    unsigned             ilbc_mode;     /**< iLBC default mode.         */ 
    6162} pjmedia_codec_passthrough_setting; 
    6263 
  • pjproject/trunk/pjmedia/src/pjmedia-codec/ilbc.c

    r2760 r2834  
    377377    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec; 
    378378    pj_status_t status; 
    379     unsigned i, dec_fmtp_mode = 0, enc_fmtp_mode = 0; 
     379    unsigned i; 
     380    pj_uint16_t dec_fmtp_mode = DEFAULT_MODE,  
     381                enc_fmtp_mode = DEFAULT_MODE; 
    380382 
    381383    pj_assert(ilbc_codec != NULL); 
     
    387389        if (pj_stricmp(&attr->setting.dec_fmtp.param[i].name, &STR_MODE) == 0) 
    388390        { 
    389             dec_fmtp_mode = (unsigned) 
     391            dec_fmtp_mode = (pj_uint16_t) 
    390392                            pj_strtoul(&attr->setting.dec_fmtp.param[i].val); 
    391393            break; 
     
    401403        if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_MODE) == 0) 
    402404        { 
    403             enc_fmtp_mode = (unsigned) 
     405            enc_fmtp_mode = (pj_uint16_t) 
    404406                            pj_strtoul(&attr->setting.enc_fmtp.param[i].val); 
    405407            break; 
     
    407409    } 
    408410 
    409     /* The enc mode must be set in the attribute  
    410      * (from the mode parameter in fmtp attribute in the SDP 
    411      * received from remote)  
     411    PJ_ASSERT_RETURN(enc_fmtp_mode==20 || enc_fmtp_mode==30,  
     412                     PJMEDIA_CODEC_EINMODE); 
     413 
     414    /* Both sides of a bi-directional session MUST use the same "mode" value. 
     415     * In this point, possible values are only 20 or 30, so when encoder and 
     416     * decoder modes are not same, just use the default mode, it is 30. 
    412417     */ 
    413     if (enc_fmtp_mode == 0) 
    414         enc_fmtp_mode = dec_fmtp_mode; 
    415  
    416     PJ_ASSERT_RETURN(enc_fmtp_mode==20 || 
    417                      enc_fmtp_mode==30, PJMEDIA_CODEC_EINMODE); 
    418  
    419     /* Update enc_ptime in the param */ 
    420418    if (enc_fmtp_mode != dec_fmtp_mode) { 
    421         attr->info.enc_ptime = (pj_uint16_t)enc_fmtp_mode; 
    422     } else { 
    423         attr->info.enc_ptime = 0; 
    424     } 
    425  
    426     /* Create enc */ 
     419        enc_fmtp_mode = dec_fmtp_mode = DEFAULT_MODE; 
     420        PJ_LOG(4,(ilbc_codec->obj_name,  
     421                  "Normalized iLBC encoder and decoder modes to %d",  
     422                  DEFAULT_MODE)); 
     423    } 
     424 
     425    /* Update some attributes based on negotiated mode. */ 
     426    attr->info.avg_bps = (dec_fmtp_mode == 30? 13333 : 15200); 
     427    attr->info.frm_ptime = dec_fmtp_mode; 
     428 
     429    /* Create encoder */ 
    427430    ilbc_codec->enc_frame_size = initEncode(&ilbc_codec->enc, enc_fmtp_mode); 
    428431    ilbc_codec->enc_samples_per_frame = CLOCK_RATE * enc_fmtp_mode / 1000; 
     
    433436                                                   dec_fmtp_mode, 
    434437                                                   attr->setting.penh); 
    435     if (dec_fmtp_mode == 20) 
    436         ilbc_codec->dec_frame_size = 38; 
    437     else if (dec_fmtp_mode == 30) 
    438         ilbc_codec->dec_frame_size = 50; 
    439     else { 
    440         pj_assert(!"Invalid iLBC mode"); 
    441         ilbc_codec->dec_frame_size = ilbc_codec->enc_frame_size; 
    442     } 
     438    ilbc_codec->dec_frame_size = (dec_fmtp_mode == 20? 38 : 50); 
    443439    ilbc_codec->dec_ready = PJ_TRUE; 
    444440 
     
    460456 
    461457    PJ_LOG(5,(ilbc_codec->obj_name,  
    462               "iLBC codec opened, encoder mode=%d, decoder mode=%d", 
    463               enc_fmtp_mode, dec_fmtp_mode)); 
     458              "iLBC codec opened, mode=%d", dec_fmtp_mode)); 
    464459 
    465460    return PJ_SUCCESS; 
  • pjproject/trunk/pjmedia/src/pjmedia-codec/passthrough.c

    r2825 r2834  
    115115    void                *codec_setting;     /**< Specific codec setting.    */ 
    116116    pj_uint16_t          avg_frame_size;    /**< Average of frame size.     */ 
     117    unsigned             samples_per_frame; /**< Samples per frame, for iLBC 
     118                                                 this can be 240 or 160, can 
     119                                                 only be known after codec is 
     120                                                 opened.                    */ 
    117121} codec_private_t; 
    118122 
     
    381385            codec_desc[i].enabled = enabled; 
    382386        } 
     387 
     388#if PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC 
     389        /* Update iLBC codec description based on default mode setting. */ 
     390        for (i = 0; i < PJ_ARRAY_SIZE(codec_desc); ++i) { 
     391            if (codec_desc[i].enabled &&  
     392                codec_desc[i].fmt_id == PJMEDIA_FORMAT_ILBC) 
     393            { 
     394                codec_desc[i].samples_per_frame =  
     395                                (setting->ilbc_mode == 20? 160 : 240); 
     396                codec_desc[i].def_bitrate =  
     397                                (setting->ilbc_mode == 20? 15200 : 13333); 
     398                pj_strset2(&codec_desc[i].dec_fmtp.param[0].val,  
     399                                (setting->ilbc_mode == 20? "20" : "30")); 
     400                break; 
     401            } 
     402        } 
     403#endif 
    383404    } 
    384405 
     
    646667    pool = codec_data->pool; 
    647668 
    648     /* Get bitstream size */ 
    649     i = attr->info.avg_bps * desc->samples_per_frame; 
     669    /* Cache samples per frame value */ 
     670    codec_data->samples_per_frame = desc->samples_per_frame; 
     671 
     672    /* Calculate bitstream size */ 
     673    i = attr->info.avg_bps * codec_data->samples_per_frame; 
    650674    j = desc->clock_rate << 3; 
    651675    codec_data->avg_frame_size = (pj_uint16_t)(i / j); 
     
    695719#endif 
    696720 
     721#if PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC 
     722    { 
     723        enum { DEFAULT_MODE = 30 }; 
     724        static pj_str_t STR_MODE = {"mode", 4}; 
     725        pj_uint16_t dec_fmtp_mode = DEFAULT_MODE,  
     726                    enc_fmtp_mode = DEFAULT_MODE; 
     727 
     728        /* Get decoder mode */ 
     729        for (i = 0; i < attr->setting.dec_fmtp.cnt; ++i) { 
     730            if (pj_stricmp(&attr->setting.dec_fmtp.param[i].name, &STR_MODE) == 0) 
     731            { 
     732                dec_fmtp_mode = (pj_uint16_t) 
     733                                pj_strtoul(&attr->setting.dec_fmtp.param[i].val); 
     734                break; 
     735            } 
     736        } 
     737 
     738        /* Decoder mode must be set */ 
     739        PJ_ASSERT_RETURN(dec_fmtp_mode == 20 || dec_fmtp_mode == 30,  
     740                         PJMEDIA_CODEC_EINMODE); 
     741 
     742        /* Get encoder mode */ 
     743        for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) { 
     744            if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_MODE) == 0) 
     745            { 
     746                enc_fmtp_mode = (pj_uint16_t) 
     747                                pj_strtoul(&attr->setting.enc_fmtp.param[i].val); 
     748                break; 
     749            } 
     750        } 
     751 
     752        PJ_ASSERT_RETURN(enc_fmtp_mode==20 || enc_fmtp_mode==30,  
     753                         PJMEDIA_CODEC_EINMODE); 
     754 
     755        /* Both sides of a bi-directional session MUST use the same "mode" value. 
     756         * In this point, possible values are only 20 or 30, so when encoder and 
     757         * decoder modes are not same, just use the default mode, it is 30. 
     758         */ 
     759        if (enc_fmtp_mode != dec_fmtp_mode) { 
     760            enc_fmtp_mode = dec_fmtp_mode = DEFAULT_MODE; 
     761            PJ_LOG(4,(pool->obj_name,  
     762                      "Normalized iLBC encoder and decoder modes to %d",  
     763                      DEFAULT_MODE)); 
     764        } 
     765 
     766        /* Update some attributes based on negotiated mode. */ 
     767        attr->info.avg_bps = (dec_fmtp_mode == 30? 13333 : 15200); 
     768        attr->info.frm_ptime = dec_fmtp_mode; 
     769 
     770        /* Override average frame size */ 
     771        codec_data->avg_frame_size = (dec_fmtp_mode == 30? 50 : 38); 
     772 
     773        /* Override samples per frame */ 
     774        codec_data->samples_per_frame = (dec_fmtp_mode == 30? 240 : 160); 
     775    } 
     776#endif 
     777 
    697778    return PJ_SUCCESS; 
    698779} 
     
    746827        frames[count].buf = pkt; 
    747828        frames[count].size = codec_data->avg_frame_size; 
    748         frames[count].timestamp.u64 = ts->u64 + count*desc->samples_per_frame; 
     829        frames[count].timestamp.u64 = ts->u64 +  
     830                                      count * codec_data->samples_per_frame; 
    749831 
    750832        pkt = (pj_uint8_t*)pkt + codec_data->avg_frame_size; 
     
    758840        frames[count].buf = pkt; 
    759841        frames[count].size = pkt_size; 
    760         frames[count].timestamp.u64 = ts->u64 + count*desc->samples_per_frame; 
     842        frames[count].timestamp.u64 = ts->u64 +  
     843                                       count * codec_data->samples_per_frame; 
    761844        ++count; 
    762845    } 
     
    855938        pjmedia_frame_ext_append_subframe(output_, input_.buf,  
    856939                                          (pj_uint16_t)(input_.size << 3), 
    857                                           (pj_uint16_t)desc->samples_per_frame); 
     940                                          (pj_uint16_t)codec_data->samples_per_frame); 
    858941        output->timestamp = input->timestamp; 
    859942         
     
    864947    pjmedia_frame_ext_append_subframe(output_, input->buf,  
    865948                                      (pj_uint16_t)(input->size << 3), 
    866                                       (pj_uint16_t)desc->samples_per_frame); 
     949                                      (pj_uint16_t)codec_data->samples_per_frame); 
    867950    output->timestamp = input->timestamp; 
    868951 
     
    884967 
    885968    pjmedia_frame_ext_append_subframe(output_, NULL, 0, 
    886                                       (pj_uint16_t)desc->samples_per_frame); 
     969                                      (pj_uint16_t)codec_data->samples_per_frame); 
    887970 
    888971    return PJ_SUCCESS; 
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r2761 r2834  
    16741674    stream->port.info.channel_count = info->fmt.channel_cnt; 
    16751675    stream->port.port_data.pdata = stream; 
    1676     if (info->param==NULL || info->param->info.fmt_id == PJMEDIA_FORMAT_L16) { 
    1677         stream->port.info.format.id = PJMEDIA_FORMAT_L16; 
    1678  
    1679         stream->port.put_frame = &put_frame; 
    1680         stream->port.get_frame = &get_frame; 
    1681     } else { 
    1682         stream->port.info.format.id = info->param->info.fmt_id; 
    1683         stream->port.info.format.bitrate = info->param->info.avg_bps; 
    1684         stream->port.info.format.vad = (info->param->setting.vad != 0); 
    1685  
    1686         stream->port.put_frame = &put_frame; 
    1687         stream->port.get_frame = &get_frame_ext; 
    1688     } 
    1689  
    16901676 
    16911677    /* Init stream: */ 
     
    17461732        stream->codec_param.setting.frm_per_pkt = 1; 
    17471733 
    1748     /* Set additional info. */ 
     1734    /* Open the codec. */ 
     1735    status = stream->codec->op->open(stream->codec, &stream->codec_param); 
     1736    if (status != PJ_SUCCESS) 
     1737        goto err_cleanup; 
     1738 
     1739    /* Set additional info and callbacks. */ 
    17491740    stream->port.info.bits_per_sample = 16; 
    17501741    stream->port.info.samples_per_frame = info->fmt.clock_rate *  
     
    17631754    } 
    17641755 
    1765     /* Open the codec: */ 
    1766  
    1767     status = stream->codec->op->open(stream->codec, &stream->codec_param); 
    1768     if (status != PJ_SUCCESS) 
    1769         goto err_cleanup; 
     1756    stream->port.info.format.id = stream->codec_param.info.fmt_id; 
     1757    if (stream->codec_param.info.fmt_id == PJMEDIA_FORMAT_L16) { 
     1758        stream->port.put_frame = &put_frame; 
     1759        stream->port.get_frame = &get_frame; 
     1760    } else { 
     1761        stream->port.info.format.bitrate = stream->codec_param.info.avg_bps; 
     1762        stream->port.info.format.vad = (stream->codec_param.setting.vad != 0); 
     1763        stream->port.put_frame = &put_frame; 
     1764        stream->port.get_frame = &get_frame_ext; 
     1765    } 
    17701766 
    17711767    /* If encoder and decoder's ptime are asymmetric, then we need to 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r2825 r2834  
    238238        setting.fmt_cnt = ext_fmt_cnt; 
    239239        setting.fmts = ext_fmts; 
     240        setting.ilbc_mode = cfg->ilbc_mode; 
    240241        status = pjmedia_codec_passthrough_init2(pjsua_var.med_endpt, &setting); 
    241242        if (status != PJ_SUCCESS) { 
Note: See TracChangeset for help on using the changeset viewer.