Ignore:
Timestamp:
Jan 23, 2013 6:18:18 AM (11 years ago)
Author:
ming
Message:

Re #1608: Add support for OpenCORE AMR-WB

File:
1 moved

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia-codec/opencore_amr.c

    r4314 r4331  
    11/* $Id$ */ 
    22/*  
    3  * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com) 
     3 * Copyright (C) 2011-2013 Teluu Inc. (http://www.teluu.com) 
    44 * Copyright (C) 2011 Dan Arrhenius <dan@keystream.se> 
    55 * 
     
    2020 
    2121/*  
    22  * AMR-NB codec implementation with OpenCORE AMRNB library 
     22 * AMR codec implementation with OpenCORE AMR library 
    2323 */ 
    2424#include <pjmedia-codec/g722.h> 
     
    3939#if defined(PJMEDIA_HAS_OPENCORE_AMRNB_CODEC) && \ 
    4040    (PJMEDIA_HAS_OPENCORE_AMRNB_CODEC != 0) 
    41  
     41#define USE_AMRNB 
     42#endif 
     43 
     44#if defined(PJMEDIA_HAS_OPENCORE_AMRWB_CODEC) && \ 
     45    (PJMEDIA_HAS_OPENCORE_AMRWB_CODEC != 0) 
     46#define USE_AMRWB 
     47#endif 
     48 
     49#if defined(USE_AMRNB) || defined(USE_AMRWB) 
     50 
     51#ifdef USE_AMRNB 
    4252#include <opencore-amrnb/interf_enc.h> 
    4353#include <opencore-amrnb/interf_dec.h> 
     54#endif 
     55 
     56#ifdef USE_AMRWB 
     57#include <vo-amrwbenc/enc_if.h> 
     58#include <opencore-amrwb/dec_if.h> 
     59#endif 
     60 
    4461#include <pjmedia-codec/amr_helper.h> 
    45 #include <pjmedia-codec/opencore_amrnb.h> 
    46  
    47 #define THIS_FILE "opencore_amrnb.c" 
     62#include <pjmedia-codec/opencore_amr.h> 
     63 
     64#define THIS_FILE "opencore_amr.c" 
    4865 
    4966/* Tracing */ 
     
    5976#define USE_PJMEDIA_PLC     1 
    6077 
    61  
    62  
    63 /* Prototypes for AMR-NB factory */ 
     78#define FRAME_LENGTH_MS     20 
     79 
     80 
     81/* Prototypes for AMR factory */ 
    6482static pj_status_t amr_test_alloc(pjmedia_codec_factory *factory,  
    6583                                   const pjmedia_codec_info *id ); 
     
    7694                                      pjmedia_codec *codec ); 
    7795 
    78 /* Prototypes for AMR-NB implementation. */ 
     96/* Prototypes for AMR implementation. */ 
    7997static pj_status_t  amr_codec_init(pjmedia_codec *codec,  
    8098                                    pj_pool_t *pool ); 
     
    104122 
    105123 
    106 /* Definition for AMR-NB codec operations. */ 
     124/* Definition for AMR codec operations. */ 
    107125static pjmedia_codec_op amr_op =  
    108126{ 
     
    117135}; 
    118136 
    119 /* Definition for AMR-NB codec factory operations. */ 
     137/* Definition for AMR codec factory operations. */ 
    120138static pjmedia_codec_factory_op amr_factory_op = 
    121139{ 
     
    129147 
    130148 
    131 /* AMR-NB factory */ 
     149/* AMR factory */ 
    132150static struct amr_codec_factory 
    133151{ 
     
    135153    pjmedia_endpt           *endpt; 
    136154    pj_pool_t               *pool; 
     155    pj_bool_t                init[2]; 
    137156} amr_codec_factory; 
    138157 
    139158 
    140 /* AMR-NB codec private data. */ 
     159/* AMR codec private data. */ 
    141160struct amr_data 
    142161{ 
    143162    pj_pool_t           *pool; 
     163    unsigned             clock_rate; 
    144164    void                *encoder; 
    145165    void                *decoder; 
     
    155175}; 
    156176 
    157 static pjmedia_codec_amrnb_config def_config = 
    158 { 
     177/* Index for AMR tables. */ 
     178enum 
     179{ 
     180    IDX_AMR_NB, /* Index for narrowband.    */ 
     181    IDX_AMR_WB  /* Index for wideband.      */ 
     182}; 
     183 
     184static pjmedia_codec_amr_config def_config[2] = 
     185{{ /* AMR-NB */ 
    159186    PJ_FALSE,       /* octet align      */ 
    160187    5900            /* bitrate          */ 
    161 }; 
    162  
    163  
    164  
    165 /* 
    166  * Initialize and register AMR-NB codec factory to pjmedia endpoint. 
    167  */ 
    168 PJ_DEF(pj_status_t) pjmedia_codec_opencore_amrnb_init( pjmedia_endpt *endpt ) 
     188 }, 
     189 { /* AMR-WB */ 
     190    PJ_FALSE,       /* octet align      */ 
     191    12650           /* bitrate          */ 
     192 }}; 
     193 
     194static const pj_uint16_t* amr_bitrates[2] = 
     195    {pjmedia_codec_amrnb_bitrates, pjmedia_codec_amrwb_bitrates}; 
     196 
     197 
     198/* 
     199 * Initialize and register AMR codec factory to pjmedia endpoint. 
     200 */ 
     201static pj_status_t amr_init( pjmedia_endpt *endpt ) 
    169202{ 
    170203    pjmedia_codec_mgr *codec_mgr; 
     
    175208        return PJ_SUCCESS; 
    176209 
    177     /* Create AMR-NB codec factory. */ 
     210    /* Create AMR codec factory. */ 
    178211    amr_codec_factory.base.op = &amr_factory_op; 
    179212    amr_codec_factory.base.factory_data = NULL; 
    180213    amr_codec_factory.endpt = endpt; 
    181214 
    182     amr_codec_factory.pool = pjmedia_endpt_create_pool(endpt, "amrnb", 1000,  
     215    amr_codec_factory.pool = pjmedia_endpt_create_pool(endpt, "amr", 1000,  
    183216                                                       1000); 
    184217    if (!amr_codec_factory.pool) 
     
    215248} 
    216249 
    217  
    218 /* 
    219  * Unregister AMR-NB codec factory from pjmedia endpoint and deinitialize 
    220  * the AMR-NB codec library. 
    221  */ 
    222 PJ_DEF(pj_status_t) pjmedia_codec_opencore_amrnb_deinit(void) 
     250PJ_DEF(pj_status_t) pjmedia_codec_opencore_amrnb_init( pjmedia_endpt *endpt ) 
     251{ 
     252    amr_codec_factory.init[IDX_AMR_NB] = PJ_TRUE; 
     253     
     254    return amr_init(endpt); 
     255} 
     256 
     257PJ_DEF(pj_status_t) pjmedia_codec_opencore_amrwb_init( pjmedia_endpt *endpt ) 
     258{ 
     259    amr_codec_factory.init[IDX_AMR_WB] = PJ_TRUE; 
     260     
     261    return amr_init(endpt);     
     262} 
     263 
     264 
     265/* 
     266 * Unregister AMR codec factory from pjmedia endpoint and deinitialize 
     267 * the AMR codec library. 
     268 */ 
     269static pj_status_t amr_deinit(void) 
    223270{ 
    224271    pjmedia_codec_mgr *codec_mgr; 
    225272    pj_status_t status; 
    226273 
     274    if (amr_codec_factory.init[IDX_AMR_NB] || 
     275        amr_codec_factory.init[IDX_AMR_WB]) 
     276    { 
     277        return PJ_SUCCESS; 
     278    } 
     279     
    227280    if (amr_codec_factory.pool == NULL) 
    228281        return PJ_SUCCESS; 
     
    236289    } 
    237290 
    238     /* Unregister AMR-NB codec factory. */ 
     291    /* Unregister AMR codec factory. */ 
    239292    status = pjmedia_codec_mgr_unregister_factory(codec_mgr, 
    240293                                                  &amr_codec_factory.base); 
     
    247300} 
    248301 
    249  
    250 PJ_DEF(pj_status_t) pjmedia_codec_opencore_amrnb_set_config( 
    251                             const pjmedia_codec_amrnb_config *config) 
     302PJ_DEF(pj_status_t) pjmedia_codec_opencore_amrnb_deinit(void) 
     303{ 
     304    amr_codec_factory.init[IDX_AMR_NB] = PJ_FALSE; 
     305     
     306    return amr_deinit(); 
     307} 
     308 
     309PJ_DEF(pj_status_t) pjmedia_codec_opencore_amrwb_deinit(void) 
     310{ 
     311    amr_codec_factory.init[IDX_AMR_WB] = PJ_FALSE; 
     312     
     313    return amr_deinit(); 
     314} 
     315 
     316static pj_status_t 
     317amr_set_config(unsigned idx, const pjmedia_codec_amr_config *config) 
    252318{ 
    253319    unsigned nbitrates; 
    254320 
    255  
    256     def_config = *config; 
     321    def_config[idx] = *config; 
    257322 
    258323    /* Normalize bitrate. */ 
    259     nbitrates = PJ_ARRAY_SIZE(pjmedia_codec_amrnb_bitrates); 
    260     if (def_config.bitrate < pjmedia_codec_amrnb_bitrates[0]) 
    261         def_config.bitrate = pjmedia_codec_amrnb_bitrates[0]; 
    262     else if (def_config.bitrate > pjmedia_codec_amrnb_bitrates[nbitrates-1]) 
    263         def_config.bitrate = pjmedia_codec_amrnb_bitrates[nbitrates-1]; 
    264     else 
     324    nbitrates = PJ_ARRAY_SIZE(amr_bitrates[idx]); 
     325    if (def_config[idx].bitrate < amr_bitrates[idx][0]) { 
     326        def_config[idx].bitrate = amr_bitrates[idx][0]; 
     327    } else if (def_config[idx].bitrate > amr_bitrates[idx][nbitrates-1]) { 
     328        def_config[idx].bitrate = amr_bitrates[idx][nbitrates-1]; 
     329    } else 
    265330    { 
    266331        unsigned i; 
    267332         
    268333        for (i = 0; i < nbitrates; ++i) { 
    269             if (def_config.bitrate <= pjmedia_codec_amrnb_bitrates[i]) 
     334            if (def_config[idx].bitrate <= amr_bitrates[idx][i]) 
    270335                break; 
    271336        } 
    272         def_config.bitrate = pjmedia_codec_amrnb_bitrates[i]; 
    273     } 
    274  
    275     return PJ_SUCCESS; 
    276 } 
    277  
    278 /*  
    279  * Check if factory can allocate the specified codec.  
     337        def_config[idx].bitrate = amr_bitrates[idx][i]; 
     338    } 
     339 
     340    return PJ_SUCCESS; 
     341} 
     342 
     343PJ_DEF(pj_status_t) pjmedia_codec_opencore_amrnb_set_config( 
     344                                    const pjmedia_codec_amrnb_config *config) 
     345{ 
     346    return amr_set_config(IDX_AMR_NB, (const pjmedia_codec_amr_config *)config); 
     347} 
     348 
     349PJ_DEF(pj_status_t) pjmedia_codec_opencore_amrwb_set_config( 
     350                                    const pjmedia_codec_amrwb_config *config) 
     351{ 
     352    return amr_set_config(IDX_AMR_WB, (const pjmedia_codec_amr_config *)config); 
     353} 
     354 
     355/* 
     356 * Check if factory can allocate the specified codec. 
    280357 */ 
    281358static pj_status_t amr_test_alloc( pjmedia_codec_factory *factory,  
    282359                                   const pjmedia_codec_info *info ) 
    283360{ 
     361    const pj_str_t amr_tag = { "AMR", 3}; 
     362    const pj_str_t amrwb_tag = { "AMR-WB", 6}; 
    284363    PJ_UNUSED_ARG(factory); 
    285364 
     365    /* Type MUST be audio. */ 
     366    if (info->type != PJMEDIA_TYPE_AUDIO) 
     367        return PJMEDIA_CODEC_EUNSUP; 
     368     
    286369    /* Check payload type. */ 
    287     if (info->pt != PJMEDIA_RTP_PT_AMR) 
     370    if (info->pt != PJMEDIA_RTP_PT_AMR && info->pt != PJMEDIA_RTP_PT_AMRWB) 
    288371        return PJMEDIA_CODEC_EUNSUP; 
    289  
    290     /* Ignore the rest, since it's static payload type. */ 
    291  
    292     return PJ_SUCCESS; 
     372     
     373    /* Check encoding name. */ 
     374    if (pj_stricmp(&info->encoding_name, &amr_tag) != 0 && 
     375        pj_stricmp(&info->encoding_name, &amrwb_tag) != 0) 
     376    { 
     377        return PJMEDIA_CODEC_EUNSUP; 
     378    } 
     379     
     380    /* Check clock-rate */ 
     381    if ((info->clock_rate == 8000 && amr_codec_factory.init[IDX_AMR_NB]) || 
     382        (info->clock_rate == 16000 && amr_codec_factory.init[IDX_AMR_WB])) 
     383    { 
     384        return PJ_SUCCESS; 
     385    } 
     386 
     387    /* Unsupported or disabled. */ 
     388    return PJMEDIA_CODEC_EUNSUP; 
    293389} 
    294390 
     
    300396                                     pjmedia_codec_param *attr ) 
    301397{ 
     398    unsigned idx; 
     399     
    302400    PJ_UNUSED_ARG(factory); 
    303     PJ_UNUSED_ARG(id); 
    304  
     401 
     402    idx = (id->clock_rate <= 8000? IDX_AMR_NB: IDX_AMR_WB); 
    305403    pj_bzero(attr, sizeof(pjmedia_codec_param)); 
    306     attr->info.clock_rate = 8000; 
     404    attr->info.clock_rate = (id->clock_rate <= 8000? 8000: 16000); 
    307405    attr->info.channel_cnt = 1; 
    308     attr->info.avg_bps = def_config.bitrate; 
    309     attr->info.max_bps = pjmedia_codec_amrnb_bitrates[7]; 
     406    attr->info.avg_bps = def_config[idx].bitrate; 
     407    attr->info.max_bps = amr_bitrates[idx][PJ_ARRAY_SIZE(amr_bitrates[idx])-1]; 
    310408    attr->info.pcm_bits_per_sample = 16; 
    311409    attr->info.frm_ptime = 20; 
    312     attr->info.pt = PJMEDIA_RTP_PT_AMR; 
     410    attr->info.pt = (pj_uint8_t)id->pt; 
    313411 
    314412    attr->setting.frm_per_pkt = 2; 
     
    316414    attr->setting.plc = 1; 
    317415 
    318     if (def_config.octet_align) { 
     416    if (def_config[idx].octet_align) { 
    319417        attr->setting.dec_fmtp.cnt = 1; 
    320418        attr->setting.dec_fmtp.param[0].name = pj_str("octet-align"); 
     
    329427 
    330428/* 
    331  * Enum codecs supported by this factory (i.e. only AMR-NB!). 
     429 * Enum codecs supported by this factory (i.e. AMR-NB and AMR-WB). 
    332430 */ 
    333431static pj_status_t amr_enum_codecs( pjmedia_codec_factory *factory,  
     
    338436    PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL); 
    339437 
    340     pj_bzero(&codecs[0], sizeof(pjmedia_codec_info)); 
    341     codecs[0].encoding_name = pj_str("AMR"); 
    342     codecs[0].pt = PJMEDIA_RTP_PT_AMR; 
    343     codecs[0].type = PJMEDIA_TYPE_AUDIO; 
    344     codecs[0].clock_rate = 8000; 
    345     codecs[0].channel_cnt = 1; 
    346  
    347     *count = 1; 
    348  
    349     return PJ_SUCCESS; 
    350 } 
    351  
    352  
    353 /* 
    354  * Allocate a new AMR-NB codec instance. 
     438    *count = 0; 
     439 
     440    if (amr_codec_factory.init[IDX_AMR_NB]) { 
     441        pj_bzero(&codecs[*count], sizeof(pjmedia_codec_info)); 
     442        codecs[*count].encoding_name = pj_str("AMR"); 
     443        codecs[*count].pt = PJMEDIA_RTP_PT_AMR; 
     444        codecs[*count].type = PJMEDIA_TYPE_AUDIO; 
     445        codecs[*count].clock_rate = 8000; 
     446        codecs[*count].channel_cnt = 1; 
     447        (*count)++; 
     448    } 
     449     
     450    if (amr_codec_factory.init[IDX_AMR_NB]) { 
     451        pj_bzero(&codecs[*count], sizeof(pjmedia_codec_info)); 
     452        codecs[*count].encoding_name = pj_str("AMR-WB"); 
     453        codecs[*count].pt = PJMEDIA_RTP_PT_AMRWB; 
     454        codecs[*count].type = PJMEDIA_TYPE_AUDIO; 
     455        codecs[*count].clock_rate = 16000; 
     456        codecs[*count].channel_cnt = 1; 
     457        (*count)++; 
     458    } 
     459 
     460    return PJ_SUCCESS; 
     461} 
     462 
     463 
     464/* 
     465 * Allocate a new AMR codec instance. 
    355466 */ 
    356467static pj_status_t amr_alloc_codec( pjmedia_codec_factory *factory,  
     
    366477    PJ_ASSERT_RETURN(factory == &amr_codec_factory.base, PJ_EINVAL); 
    367478 
    368     pool = pjmedia_endpt_create_pool(amr_codec_factory.endpt, "amrnb-inst",  
     479    pool = pjmedia_endpt_create_pool(amr_codec_factory.endpt, "amr-inst",  
    369480                                     512, 512); 
    370481 
     
    380491#if USE_PJMEDIA_PLC 
    381492    /* Create PLC */ 
    382     status = pjmedia_plc_create(pool, 8000, 160, 0, &amr_data->plc); 
     493    status = pjmedia_plc_create(pool, id->clock_rate, 
     494                                id->clock_rate * FRAME_LENGTH_MS / 1000, 0, 
     495                                &amr_data->plc); 
    383496    if (status != PJ_SUCCESS) { 
    384497        return status; 
     
    438551    pj_int8_t enc_mode; 
    439552    const pj_str_t STR_FMTP_OCTET_ALIGN = {"octet-align", 11}; 
     553    unsigned idx; 
    440554 
    441555    PJ_ASSERT_RETURN(codec && attr, PJ_EINVAL); 
    442556    PJ_ASSERT_RETURN(amr_data != NULL, PJ_EINVALIDOP); 
    443557 
     558    idx = (attr->info.clock_rate <= 8000? IDX_AMR_NB: IDX_AMR_WB); 
    444559    enc_mode = pjmedia_codec_amr_get_mode(attr->info.avg_bps); 
    445     pj_assert(enc_mode >= 0 && enc_mode <= 7); 
     560    pj_assert(enc_mode >= 0 && 
     561              enc_mode < PJ_ARRAY_SIZE(amr_bitrates[idx])); 
    446562 
    447563    /* Check octet-align */ 
     
    477593            l = pj_strlen(&attr->setting.enc_fmtp.param[i].val); 
    478594            while (l--) { 
    479                 if (*p>='0' && *p<='7') { 
     595                if (*p>='0' && 
     596                    *p<=('0'+PJ_ARRAY_SIZE(amr_bitrates[idx])-1)) 
     597                { 
    480598                    pj_int8_t tmp = *p - '0' - enc_mode; 
    481599 
     
    497615    } 
    498616 
     617    amr_data->clock_rate = attr->info.clock_rate; 
    499618    amr_data->vad_enabled = (attr->setting.vad != 0); 
    500619    amr_data->plc_enabled = (attr->setting.plc != 0); 
    501620    amr_data->enc_mode = enc_mode; 
    502621 
    503     amr_data->encoder = Encoder_Interface_init(amr_data->vad_enabled); 
     622    if (idx == IDX_AMR_NB) { 
     623#ifdef USE_AMRNB 
     624        amr_data->encoder = Encoder_Interface_init(amr_data->vad_enabled); 
     625#endif 
     626    } else { 
     627#ifdef USE_AMRWB 
     628        amr_data->encoder = E_IF_init(); 
     629#endif 
     630    } 
    504631    if (amr_data->encoder == NULL) { 
    505         TRACE_((THIS_FILE, "Encoder_Interface_init() failed")); 
     632        TRACE_((THIS_FILE, "Encoder initialization failed")); 
    506633        amr_codec_close(codec); 
    507634        return PJMEDIA_CODEC_EFAILED; 
     
    509636    setting = &amr_data->enc_setting; 
    510637    pj_bzero(setting, sizeof(pjmedia_codec_amr_pack_setting)); 
    511     setting->amr_nb = 1; 
     638    setting->amr_nb = (idx == IDX_AMR_NB? 1: 0); 
    512639    setting->reorder = 0; 
    513640    setting->octet_aligned = octet_align; 
    514641    setting->cmr = 15; 
    515642 
    516     amr_data->decoder = Decoder_Interface_init(); 
     643    if (idx == IDX_AMR_NB) { 
     644#ifdef USE_AMRNB 
     645        amr_data->decoder = Decoder_Interface_init(); 
     646#endif 
     647    } else { 
     648#ifdef USE_AMRWB 
     649        amr_data->decoder = D_IF_init(); 
     650#endif 
     651    } 
    517652    if (amr_data->decoder == NULL) { 
    518         TRACE_((THIS_FILE, "Decoder_Interface_init() failed")); 
     653        TRACE_((THIS_FILE, "Decoder initialization failed")); 
    519654        amr_codec_close(codec); 
    520655        return PJMEDIA_CODEC_EFAILED; 
     
    522657    setting = &amr_data->dec_setting; 
    523658    pj_bzero(setting, sizeof(pjmedia_codec_amr_pack_setting)); 
    524     setting->amr_nb = 1; 
     659    setting->amr_nb = (idx == IDX_AMR_NB? 1: 0); 
    525660    setting->reorder = 0; 
    526661    setting->octet_aligned = octet_align; 
    527662 
    528     TRACE_((THIS_FILE, "AMR-NB codec allocated: vad=%d, plc=%d, bitrate=%d", 
     663    TRACE_((THIS_FILE, "AMR codec allocated: clockrate=%d vad=%d, plc=%d," 
     664                       " bitrate=%d", amr_data->clock_rate, 
    529665                        amr_data->vad_enabled, amr_data->plc_enabled,  
    530                         pjmedia_codec_amrnb_bitrates[amr_data->enc_mode])); 
     666                        amr_bitrates[idx][amr_data->enc_mode])); 
    531667    return PJ_SUCCESS; 
    532668} 
     
    546682 
    547683    if (amr_data->encoder) { 
    548         Encoder_Interface_exit(amr_data->encoder); 
     684        if (amr_data->enc_setting.amr_nb) { 
     685#ifdef USE_AMRNB 
     686            Encoder_Interface_exit(amr_data->encoder); 
     687#endif 
     688        } else { 
     689#ifdef USE_AMRWB 
     690            E_IF_exit(amr_data->encoder); 
     691#endif 
     692        } 
    549693        amr_data->encoder = NULL; 
    550694    } 
    551695 
    552696    if (amr_data->decoder) { 
    553         Decoder_Interface_exit(amr_data->decoder); 
     697        if (amr_data->dec_setting.amr_nb) { 
     698#ifdef USE_AMRNB 
     699            Decoder_Interface_exit(amr_data->decoder); 
     700#endif 
     701        } else { 
     702#ifdef USE_AMRWB 
     703            D_IF_exit(amr_data->decoder); 
     704#endif 
     705        } 
    554706        amr_data->decoder = NULL; 
    555707    } 
    556708     
    557     TRACE_((THIS_FILE, "AMR-NB codec closed")); 
     709    TRACE_((THIS_FILE, "AMR codec closed")); 
    558710    return PJ_SUCCESS; 
    559711} 
     
    576728    amr_data->plc_enabled = (attr->setting.plc != 0); 
    577729 
    578     if (prev_vad_state != amr_data->vad_enabled) { 
     730    if (amr_data->enc_setting.amr_nb && 
     731        prev_vad_state != amr_data->vad_enabled) 
     732    { 
    579733        /* Reinit AMR encoder to update VAD setting */ 
    580734        TRACE_((THIS_FILE, "Reiniting AMR encoder to update VAD setting.")); 
     735#ifdef USE_AMRNB 
    581736        Encoder_Interface_exit(amr_data->encoder); 
    582737        amr_data->encoder = Encoder_Interface_init(amr_data->vad_enabled); 
     738#endif 
    583739        if (amr_data->encoder == NULL) { 
    584740            TRACE_((THIS_FILE, "Encoder_Interface_init() failed")); 
     
    588744    } 
    589745 
    590     TRACE_((THIS_FILE, "AMR-NB codec modified: vad=%d, plc=%d", 
     746    TRACE_((THIS_FILE, "AMR codec modified: vad=%d, plc=%d", 
    591747                        amr_data->vad_enabled, amr_data->plc_enabled)); 
    592748    return PJ_SUCCESS; 
     
    607763    pj_uint8_t cmr; 
    608764    pj_status_t status; 
     765    unsigned idx = (amr_data->enc_setting.amr_nb? 0: 1); 
    609766 
    610767    status = pjmedia_codec_amr_parse(pkt, pkt_size, ts, &amr_data->dec_setting, 
     
    614771 
    615772    /* Check for Change Mode Request. */ 
    616     if (cmr <= 7 && amr_data->enc_mode != cmr) { 
     773    if (cmr < PJ_ARRAY_SIZE(amr_bitrates[idx]) && amr_data->enc_mode != cmr) { 
    617774        amr_data->enc_mode = cmr; 
    618         TRACE_((THIS_FILE, "AMR-NB encoder switched mode to %d (%dbps)", 
    619                             amr_data->enc_mode,  
    620                             pjmedia_codec_amrnb_bitrates[amr_data->enc_mode])); 
     775        TRACE_((THIS_FILE, "AMR encoder switched mode to %d (%dbps)", 
     776                amr_data->enc_mode,  
     777                amr_bitrates[idx][amr_data->enc_mode])); 
    621778    } 
    622779 
     
    650807 
    651808    nsamples = input->size >> 1; 
    652     samples_per_frame = 160; 
     809    samples_per_frame = amr_data->clock_rate * FRAME_LENGTH_MS / 1000; 
    653810    PJ_ASSERT_RETURN(nsamples % samples_per_frame == 0,  
    654811                     PJMEDIA_CODEC_EPCMFRMINLEN); 
     
    662819    bitstream = (unsigned char*)output->buf; 
    663820    while (nsamples >= samples_per_frame) { 
    664         size = Encoder_Interface_Encode (amr_data->encoder, amr_data->enc_mode, 
    665                                          speech, bitstream, 0); 
     821        if (amr_data->enc_setting.amr_nb) { 
     822#ifdef USE_AMRNB 
     823            size = Encoder_Interface_Encode (amr_data->encoder, 
     824                                             amr_data->enc_mode, 
     825                                             speech, bitstream, 0); 
     826#endif 
     827        } else { 
     828#ifdef USE_AMRWB 
     829            size = E_IF_encode (amr_data->encoder, amr_data->enc_mode, 
     830                                speech, bitstream, 0); 
     831#endif 
     832        } 
    666833        if (size == 0) { 
    667834            output->size = 0; 
    668835            output->buf = NULL; 
    669836            output->type = PJMEDIA_FRAME_TYPE_NONE; 
    670             TRACE_((THIS_FILE, "AMR-NB encode() failed")); 
     837            TRACE_((THIS_FILE, "AMR encode() failed")); 
    671838            return PJMEDIA_CODEC_EFAILED; 
    672839        } 
    673         nsamples -= 160; 
     840        nsamples -= samples_per_frame; 
    674841        speech += samples_per_frame; 
    675842        bitstream += size; 
    676843        out_size += size; 
    677         TRACE_((THIS_FILE, "AMR-NB encode(): mode=%d, size=%d", 
     844        TRACE_((THIS_FILE, "AMR encode(): mode=%d, size=%d", 
    678845                amr_data->enc_mode, out_size)); 
    679846    } 
     
    691858        info->start_bit = 0; 
    692859        frames[i].buf = p + 1; 
    693         frames[i].size = (info->frame_type <= 8)?  
    694                          pjmedia_codec_amrnb_framelen[info->frame_type] : 0; 
     860        if (amr_data->enc_setting.amr_nb) { 
     861            frames[i].size = (info->frame_type <= 8)? 
     862                             pjmedia_codec_amrnb_framelen[info->frame_type] : 0; 
     863        } else { 
     864            frames[i].size = (info->frame_type <= 9)? 
     865                             pjmedia_codec_amrwb_framelen[info->frame_type] : 0; 
     866        } 
    695867        p += frames[i].size + 1; 
    696868 
     
    714886                                           &input->timestamp); 
    715887        if (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 || 
    716             dtx_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*8000/1000)  
     888            dtx_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD* 
     889                           amr_data->clock_rate/1000) 
    717890        { 
    718891            output->size = 0; 
     
    756929    pjmedia_frame input_; 
    757930    pjmedia_codec_amr_bit_info *info; 
    758     /* VA AMR-NB decoding buffer: AMR-NB max frame size + 1 byte header. */ 
    759     unsigned char bitstream[32]; 
     931    unsigned out_size; 
     932    /* AMR decoding buffer: AMR max frame size + 1 byte header. */ 
     933    unsigned char bitstream[61]; 
    760934 
    761935    pj_assert(amr_data != NULL); 
    762936    PJ_ASSERT_RETURN(input && output, PJ_EINVAL); 
    763937 
    764     if (output_buf_len < 320) 
     938    out_size = amr_data->clock_rate * FRAME_LENGTH_MS / 1000 * 2; 
     939    if (output_buf_len < out_size) 
    765940        return PJMEDIA_CODEC_EPCMTOOSHORT; 
    766941 
    767942    input_.buf = &bitstream[1]; 
    768     input_.size = 31; /* AMR-NB max frame size */ 
     943    /* AMR max frame size */ 
     944    input_.size = (amr_data->dec_setting.amr_nb? 31: 60); 
    769945    pjmedia_codec_amr_predecode(input, &amr_data->dec_setting, &input_); 
    770946    info = (pjmedia_codec_amr_bit_info*)&input_.bit_info; 
    771947 
    772     /* VA AMRNB decoder requires frame info in the first byte. */ 
     948    /* VA AMR decoder requires frame info in the first byte. */ 
    773949    bitstream[0] = (info->frame_type << 3) | (info->good_quality << 2); 
    774950 
    775     TRACE_((THIS_FILE, "AMR-NB decode(): mode=%d, ft=%d, size=%d", 
     951    TRACE_((THIS_FILE, "AMR decode(): mode=%d, ft=%d, size=%d", 
    776952            info->mode, info->frame_type, input_.size)); 
    777953 
    778954    /* Decode */ 
    779     Decoder_Interface_Decode(amr_data->decoder, bitstream, 
    780                              (pj_int16_t*)output->buf, 0); 
    781  
    782     output->size = 320; 
     955    if (amr_data->dec_setting.amr_nb) { 
     956#ifdef USE_AMRNB 
     957        Decoder_Interface_Decode(amr_data->decoder, bitstream, 
     958                                 (pj_int16_t*)output->buf, 0); 
     959#endif 
     960    } else { 
     961#ifdef USE_AMRWB 
     962        D_IF_decode(amr_data->decoder, bitstream, 
     963                    (pj_int16_t*)output->buf, 0); 
     964#endif 
     965    } 
     966 
     967    output->size = out_size; 
    783968    output->type = PJMEDIA_FRAME_TYPE_AUDIO; 
    784969    output->timestamp = input->timestamp; 
     
    805990{ 
    806991    struct amr_data *amr_data = codec->codec_data; 
     992    unsigned out_size = amr_data->clock_rate * FRAME_LENGTH_MS / 1000 * 2; 
    807993 
    808994    TRACE_((THIS_FILE, "amr_codec_recover")); 
     
    810996    PJ_ASSERT_RETURN(amr_data->plc_enabled, PJ_EINVALIDOP); 
    811997 
    812     PJ_ASSERT_RETURN(output_buf_len >= 320,  PJMEDIA_CODEC_EPCMTOOSHORT); 
     998    PJ_ASSERT_RETURN(output_buf_len >= out_size,  PJMEDIA_CODEC_EPCMTOOSHORT); 
    813999 
    8141000    pjmedia_plc_generate(amr_data->plc, (pj_int16_t*)output->buf); 
    8151001 
    816     output->size = 320; 
     1002    output->size = out_size; 
    8171003    output->type = PJMEDIA_FRAME_TYPE_AUDIO; 
    8181004     
     
    8221008 
    8231009#if defined(_MSC_VER) && PJMEDIA_AUTO_LINK_OPENCORE_AMR_LIBS 
    824 #  if PJMEDIA_OPENCORE_AMR_BUILT_WITH_GCC 
    825 #   pragma comment( lib, "libopencore-amrnb.a") 
    826 #  else 
    827 #   error Unsupported OpenCORE AMR library, fix here 
    828 #  endif 
    829 #endif 
    830  
    831 #endif 
     1010#   if PJMEDIA_OPENCORE_AMR_BUILT_WITH_GCC 
     1011#       ifdef USE_AMRNB 
     1012#           pragma comment( lib, "libopencore-amrnb.a") 
     1013#       endif 
     1014#       ifdef USE_AMRWB 
     1015#           pragma comment( lib, "libopencore-amrwb.a") 
     1016#           pragma comment( lib, "libvo-amrwbenc.a") 
     1017#       endif 
     1018#   else 
     1019#       error Unsupported OpenCORE AMR library, fix here 
     1020#   endif 
     1021#endif 
     1022 
     1023#endif 
Note: See TracChangeset for help on using the changeset viewer.