Changeset 2359


Ignore:
Timestamp:
Oct 29, 2008 10:17:02 AM (11 years ago)
Author:
nanang
Message:

Ticket #670:

  • Configurable setting to enable/disable AMR bitstream reordering (sensitivity order to/from encoder bits order).
  • Updated AMR codec to regard in-band Change Mode Request from remote encoder.
  • Updated AMR settings (octet-align, etc) to be configured upon codec opening, instead of hardcoded in the encode, decode, parse.
Location:
pjproject/trunk/pjmedia
Files:
2 edited

Legend:

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

    r2358 r2359  
    605605    pj_int8_t  mode;            /**< AMR mode.                          */ 
    606606    pj_uint8_t start_bit;       /**< Frame start bit.                   */ 
    607     pj_uint8_t good_quality:1;  /**< Flag if frame contains good data.  */ 
     607    pj_uint8_t good_quality:1;  /**< Flag if frame is good/degraded.    */ 
    608608} pjmedia_codec_amr_bit_info; 
    609609#pragma pack() 
     
    614614 */ 
    615615typedef struct pjmedia_codec_amr_settings { 
    616     pj_bool_t  amr_nb;          /**< TRUE for AMR-NB, FALSE for AMR-WB  */ 
    617     pj_uint8_t CMR;             /**< Change Mode Request,  
    618                                      in band message from encoder.      */ 
     616    pj_bool_t  amr_nb;          /**< TRUE for AMR-NB, FALSE for AMR-WB. */ 
     617    pj_bool_t  reorder;         /**< Reorder bitstream into descending  
     618                                     sensitivity order or vice versa.   */ 
    619619    pj_uint8_t octet_aligned;   /**< TRUE if payload is in octet-aligned mode, 
    620620                                     FALSE if payload is in bandwidth  
    621621                                     efficient mode.                    */ 
     622    pj_uint8_t CMR;             /**< Change Mode Request for remote 
     623                                     encoder.                           */ 
    622624} pjmedia_codec_amr_settings; 
    623625 
     
    631633 */ 
    632634 
    633 PJ_INLINE(int) pjmedia_codec_amr_get_mode(unsigned bitrate) 
    634 { 
    635     int mode = -1; 
     635PJ_INLINE(pj_int8_t) pjmedia_codec_amr_get_mode(unsigned bitrate) 
     636{ 
     637    pj_int8_t mode = -1; 
    636638 
    637639    if(bitrate==4750){ 
     
    676678 
    677679/** 
    678  * Rearrange AMR bitstream from sensitivity bits order into encoder bits order. 
    679  * This will also make the start_bit to be 0. Basically this function should be 
    680  * called before invoking decoder. 
     680 * Prepare a frame before pass it to decoder. This function will do: 
     681 * - reorder AMR bitstream from descending sensitivity order into  
     682 *   encoder bits order. This can be enabled/disabled via param  
     683 *   'setting' by setting/resetting field 'reorder'. 
     684 * - align left the start bit (make the start_bit to be 0). 
    681685 * 
    682686 * @param amr_nb    Set PJ_TRUE for AMR-NB and PJ_FALSE for AMR-WB. 
    683687 * @param in        Input frame. 
     688 * @param setting   Settings, see @pjmedia_codec_amr_settings. 
    684689 * @param out       Output frame. 
    685690 * 
    686691 * @return          PJ_SUCCESS on success. 
    687692 */ 
    688 PJ_INLINE(pj_status_t) pjmedia_codec_amr_reorder_sens_to_enc( 
    689                                                 pj_bool_t amr_nb, 
    690                                                 const pjmedia_frame *in, 
    691                                                 pjmedia_frame *out) 
     693PJ_INLINE(pj_status_t) pjmedia_codec_amr_predecode( 
     694                                    const pjmedia_frame *in, 
     695                                    const pjmedia_codec_amr_settings *setting, 
     696                                    pjmedia_frame *out) 
    692697{ 
    693698    pj_int8_t    amr_bits[477 + 7] = {0}; 
     
    713718    *out_info = *in_info; 
    714719 
    715     if (amr_nb) { 
     720    if (setting->amr_nb) { 
    716721        SID_FT          = 8; 
    717722        framelen_tbl    = pjmedia_codec_amrnb_framelen; 
     
    751756 
    752757        /* Speech */ 
    753         const pj_int16_t *order_map; 
    754  
    755758        out_info->mode = in_info->frame_type; 
    756759        out->size = framelen_tbl[out_info->mode]; 
    757760        PJ_ASSERT_RETURN(out->size <= in->size, PJMEDIA_CODEC_EFRMINLEN); 
    758761 
    759         order_map = order_maps[out_info->mode]; 
    760762        pj_bzero(out->buf, out->size); 
    761         for(i = 0; i < framelenbit_tbl[out_info->mode]; ++i) { 
    762             if (amr_bits[i]) { 
    763                 pj_uint16_t bitpos; 
    764                 bitpos = order_map[i]; 
    765                 w[bitpos>>3] |= 1 << (7 - (bitpos % 8)); 
     763 
     764        if (setting->reorder) { 
     765            const pj_int16_t *order_map; 
     766 
     767            order_map = order_maps[out_info->mode]; 
     768            for(i = 0; i < framelenbit_tbl[out_info->mode]; ++i) { 
     769                if (amr_bits[i]) { 
     770                    pj_uint16_t bitpos; 
     771                    bitpos = order_map[i]; 
     772                    w[bitpos>>3] |= 1 << (7 - (bitpos % 8)); 
     773                } 
     774            } 
     775        } else { 
     776            for(i = 0; i < framelenbit_tbl[out_info->mode]; ++i) { 
     777                if (amr_bits[i]) 
     778                    w[i >> 3] |= 1 << (7 - (i % 8)); 
    766779            } 
    767780        } 
     
    773786        pj_uint8_t FT_; 
    774787 
    775         if (amr_nb) 
     788        if (setting->amr_nb) 
    776789            FT_ = (pj_uint8_t)((amr_bits[36] << 2) | (amr_bits[37] << 1) |  
    777790                               amr_bits[38]); 
     
    949962 
    950963            /* Speech */ 
    951             const pj_int16_t *order_map; 
    952  
    953             /* Put bits in the packet, sensitivity descending ordered */ 
    954             order_map = order_maps[info->frame_type]; 
    955964            if (w_bitptr == 0) *w = 0; 
    956             for(j = 0; j < framelenbit_tbl[info->frame_type]; ++j) { 
    957                 if (amr_bits[order_map[j]]) 
    958                     *w |= (1 << (7-w_bitptr)); 
    959  
    960                 if (++w_bitptr == 8) { 
    961                     w_bitptr = 0; 
    962                     ++w; 
    963                     *w = 0; 
     965 
     966            if (setting->reorder) { 
     967                const pj_int16_t *order_map; 
     968 
     969                /* Put bits in the packet, sensitivity descending ordered */ 
     970                order_map = order_maps[info->frame_type]; 
     971                for(j = 0; j < framelenbit_tbl[info->frame_type]; ++j) { 
     972                    if (amr_bits[order_map[j]]) 
     973                        *w |= (1 << (7-w_bitptr)); 
     974 
     975                    if (++w_bitptr == 8) { 
     976                        w_bitptr = 0; 
     977                        ++w; 
     978                        *w = 0; 
     979                    } 
     980                } 
     981            } else { 
     982                for(j = 0; j < framelenbit_tbl[info->frame_type]; ++j) { 
     983                    if (amr_bits[j]) 
     984                        *w |= (1 << (7-w_bitptr)); 
     985 
     986                    if (++w_bitptr == 8) { 
     987                        w_bitptr = 0; 
     988                        ++w; 
     989                        *w = 0; 
     990                    } 
    964991                } 
    965992            } 
     
    10191046 * @param frames    Frames parsed. 
    10201047 * @param nframes   Number of frames parsed. 
    1021  * @param CMR       Change Mode Request message from the encoder. 
     1048 * @param CMR       Change Mode Request message for local encoder. 
    10221049 * 
    10231050 * @return          PJ_SUCCESS on success. 
  • pjproject/trunk/pjmedia/src/pjmedia-codec/ipp_codecs.c

    r2358 r2359  
    115115typedef struct ipp_private { 
    116116    int                  codec_idx;         /**< Codec index.               */ 
     117    void                *codec_setting;     /**< Specific codec setting.    */ 
    117118    pj_pool_t           *pool;              /**< Pool for each instance.    */ 
    118119 
     
    122123    pj_uint16_t          frame_size;        /**< Bitstream frame size.      */ 
    123124 
    124     pj_bool_t            plc_enabled; 
    125     pjmedia_plc         *plc; 
    126  
    127     pj_bool_t            vad_enabled; 
    128     pjmedia_silence_det *vad; 
    129     pj_timestamp         last_tx; 
     125    pj_bool_t            plc_enabled;       /**< PLC enabled flag.          */ 
     126    pjmedia_plc         *plc;               /**< PJMEDIA PLC engine, NULL if  
     127                                                 codec has internal PLC.    */ 
     128 
     129    pj_bool_t            vad_enabled;       /**< VAD enabled flag.          */ 
     130    pjmedia_silence_det *vad;               /**< PJMEDIA VAD engine, NULL if  
     131                                                 codec has internal VAD.    */ 
     132    pj_timestamp         last_tx;           /**< Timestamp of last transmit.*/ 
    130133} ipp_private_t; 
    131134 
     
    420423#include <pjmedia-codec/amr_helper.h> 
    421424 
     425typedef struct amr_settings_t { 
     426    pjmedia_codec_amr_settings enc_setting; 
     427    pjmedia_codec_amr_settings dec_setting; 
     428    pj_int8_t enc_mode; 
     429} amr_settings_t; 
     430 
     431 
    422432/* Rearrange AMR bitstream and convert RTP frame into USC frame: 
    423433 * - make the start_bit to be 0 
     
    432442    pjmedia_frame frame; 
    433443    pjmedia_codec_amr_bit_info *info; 
    434     pj_bool_t amr_nb; 
    435  
    436     amr_nb = (ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMR); 
     444    pjmedia_codec_amr_settings *setting; 
     445 
     446    setting = &((amr_settings_t*)codec_data->codec_setting)->dec_setting; 
     447 
    437448    frame = *rtp_frame; 
    438     pjmedia_codec_amr_reorder_sens_to_enc(amr_nb, rtp_frame, &frame); 
     449    pjmedia_codec_amr_predecode(rtp_frame, setting, &frame); 
    439450    info = (pjmedia_codec_amr_bit_info*) &frame.bit_info; 
    440451 
     
    442453    usc_frame->nbytes = frame.size; 
    443454    if (info->mode != -1) { 
    444         usc_frame->bitrate = amr_nb?  
     455        usc_frame->bitrate = setting->amr_nb?  
    445456                             pjmedia_codec_amrnb_bitrates[info->mode]: 
    446457                             pjmedia_codec_amrwb_bitrates[info->mode]; 
     
    454465            usc_frame->frametype = 0; 
    455466        else 
    456             usc_frame->frametype = amr_nb ? 5 : 6; 
     467            usc_frame->frametype = setting->amr_nb ? 5 : 6; 
    457468    } else if (frame.size == 5) { 
    458469        /* SID */ 
     
    462473            usc_frame->frametype = STI? 2 : 1; 
    463474        } else { 
    464             usc_frame->frametype = amr_nb ? 6 : 7; 
     475            usc_frame->frametype = setting->amr_nb ? 6 : 7; 
    465476        } 
    466477    } else { 
     
    476487    enum {MAX_FRAMES_PER_PACKET = 16}; 
    477488 
    478     pjmedia_codec_amr_settings setting; 
    479489    pjmedia_frame frames[MAX_FRAMES_PER_PACKET]; 
    480490    unsigned nframes = 0; 
     
    482492    pj_uint8_t *r; /* Read cursor */ 
    483493    pj_uint8_t SID_FT; 
    484  
    485     setting.amr_nb = ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMR; 
    486     setting.CMR = 15; /* not requesting any mode */ 
    487     setting.octet_aligned = 0; 
    488  
    489     SID_FT = (pj_uint8_t)(setting.amr_nb? 8 : 9); 
     494    pjmedia_codec_amr_settings *setting; 
     495 
     496    setting = &((amr_settings_t*)codec_data->codec_setting)->enc_setting; 
     497 
     498    SID_FT = (pj_uint8_t)(setting->amr_nb? 8 : 9); 
    490499 
    491500    /* Align pkt buf right */ 
     
    521530    /* Pack */ 
    522531    *pkt_size = max_pkt_size; 
    523     return pjmedia_codec_amr_pack(frames, nframes, &setting, pkt, pkt_size); 
     532    return pjmedia_codec_amr_pack(frames, nframes, setting, pkt, pkt_size); 
    524533} 
    525534 
     
    530539                             unsigned *frame_cnt, pjmedia_frame frames[]) 
    531540{ 
    532     pjmedia_codec_amr_settings setting; 
     541    amr_settings_t* s = (amr_settings_t*)codec_data->codec_setting; 
     542    pjmedia_codec_amr_settings *setting; 
     543    pj_status_t status; 
    533544    pj_uint8_t CMR; 
    534545 
    535     setting.amr_nb = ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMR; 
    536     setting.octet_aligned = 0; 
    537  
    538     return pjmedia_codec_amr_parse(pkt, pkt_size, ts, &setting, frames,  
    539                                    frame_cnt, &CMR); 
     546    setting = &s->dec_setting; 
     547 
     548    status = pjmedia_codec_amr_parse(pkt, pkt_size, ts, setting, frames,  
     549                                     frame_cnt, &CMR); 
     550    if (status != PJ_SUCCESS) 
     551        return status; 
     552 
     553    /* Check Change Mode Request. */ 
     554    if ((setting->amr_nb && CMR <= 7) || (!setting->amr_nb && CMR <= 8)) { 
     555        s->enc_mode = CMR; 
     556    } 
     557 
     558    return PJ_SUCCESS; 
    540559} 
    541560 
     
    10011020    codec_data->plc_enabled = (attr->setting.plc != 0); 
    10021021 
     1022#if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR 
     1023    /* Init AMR settings */ 
     1024    if (ippc->pt == PJMEDIA_RTP_PT_AMR || ippc->pt == PJMEDIA_RTP_PT_AMRWB) { 
     1025        amr_settings_t *s; 
     1026 
     1027        s = PJ_POOL_ZALLOC_T(pool, amr_settings_t); 
     1028        codec_data->codec_setting = s; 
     1029 
     1030        s->enc_mode = pjmedia_codec_amr_get_mode(ippc->def_bitrate); 
     1031        if (s->enc_mode < 0) 
     1032            goto on_error; 
     1033 
     1034        s->enc_setting.amr_nb = ippc->pt == PJMEDIA_RTP_PT_AMR; 
     1035        s->enc_setting.octet_aligned = 0; 
     1036        s->enc_setting.reorder = PJ_TRUE; 
     1037        s->enc_setting.CMR = 15; 
     1038         
     1039        s->dec_setting.amr_nb = ippc->pt == PJMEDIA_RTP_PT_AMR; 
     1040        s->dec_setting.octet_aligned = 0; 
     1041        s->dec_setting.reorder = PJ_TRUE; 
     1042    } 
     1043#endif 
     1044 
    10031045    return PJ_SUCCESS; 
    10041046 
     
    11621204 
    11631205#if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR 
    1164         /* For AMR: put info (frametype, degraded, last frame) in the  
    1165          * first byte  
     1206        /* For AMR: put info (frametype, degraded, last frame, mode) in the  
     1207         * first two octets for payload packing. 
    11661208         */ 
    11671209        if (pt == PJMEDIA_RTP_PT_AMR || pt == PJMEDIA_RTP_PT_AMRWB) { 
Note: See TracChangeset for help on using the changeset viewer.