Ignore:
Timestamp:
Feb 9, 2009 10:39:58 AM (15 years ago)
Author:
nanang
Message:
  • Added support for codec ILBC, G729, and AMR.
  • Updated audio switch board to make user possible to update its port 0 (master port) attributes, this is needed since sound device need to be reopened (e.g: for changing ptime or codec) while conf is not recreated.
  • Added new API to AMR helper to resolve mode/frame-type based on frame len.
  • Updated pmedia_frame_ext helper functions for a bit optimization.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/conf_switch.c

    r2438 r2444  
    6868struct conf_port 
    6969{ 
     70    SLOT_TYPE            slot;          /**< Array of listeners.            */ 
    7071    pj_str_t             name;          /**< Port name.                     */ 
    7172    pjmedia_port        *port;          /**< get_frame() and put_frame()    */ 
     
    7778 
    7879    /* Shortcut for port info. */ 
    79     unsigned             clock_rate;    /**< Port's clock rate.             */ 
    80     unsigned             samples_per_frame; /**< Port's samples per frame.  */ 
    81     unsigned             channel_count; /**< Port's channel count.          */ 
     80    pjmedia_port_info   *info; 
    8281 
    8382    /* Calculated signal levels: */ 
     
    118117    pj_mutex_t           *mutex;        /**< Conference mutex.              */ 
    119118    struct conf_port    **ports;        /**< Array of ports.                */ 
    120     unsigned              clock_rate;   /**< Sampling rate.                 */ 
    121     unsigned              channel_count;/**< Number of channels (1=mono).   */ 
    122     unsigned              samples_per_frame;    /**< Samples per frame.     */ 
    123     unsigned              bits_per_sample;      /**< Bits per sample.       */ 
    124119    pj_uint8_t            buf[BUFFER_SIZE];     /**< Common buffer.         */ 
    125120}; 
     
    146141    pjmedia_frame *f; 
    147142 
     143    PJ_ASSERT_RETURN(pool && conf && port && name && p_conf_port, PJ_EINVAL); 
     144 
    148145    /* Create port. */ 
    149146    conf_port = PJ_POOL_ZALLOC_T(pool, struct conf_port); 
     
    163160 
    164161    /* Save some port's infos, for convenience. */ 
    165     if (port) { 
    166         conf_port->port = port; 
    167         conf_port->clock_rate = port->info.clock_rate; 
    168         conf_port->samples_per_frame = port->info.samples_per_frame; 
    169         conf_port->channel_count = port->info.channel_count; 
    170     } else { 
    171         conf_port->port = NULL; 
    172         conf_port->clock_rate = conf->clock_rate; 
    173         conf_port->samples_per_frame = conf->samples_per_frame; 
    174         conf_port->channel_count = conf->channel_count; 
    175     } 
     162    conf_port->port = port; 
     163    conf_port->info = &port->info; 
    176164 
    177165    /* Init pjmedia_frame structure in the TX buffer. */ 
     
    196184 
    197185 
    198     status = create_conf_port(pool, conf, NULL, &name, &conf_port); 
     186    status = create_conf_port(pool, conf, conf->master_port, &name, &conf_port); 
    199187    if (status != PJ_SUCCESS) 
    200188        return status; 
     
    206194        pjmedia_snd_stream *strm; 
    207195        pjmedia_snd_stream_info si; 
     196        pjmedia_port_info *master_port_info = (pjmedia_port_info*) 
     197                                              &conf->master_port->info; 
    208198 
    209199        /* 
     
    212202         */ 
    213203        if (conf->options & PJMEDIA_CONF_NO_MIC)  { 
    214             status = pjmedia_snd_port_create_player(pool, -1, conf->clock_rate, 
    215                                                     conf->channel_count, 
    216                                                     conf->samples_per_frame, 
    217                                                     conf->bits_per_sample,  
    218                                                     0,  /* options */ 
    219                                                     &conf->snd_dev_port); 
     204            status = pjmedia_snd_port_create_player( 
     205                                        pool, -1,  
     206                                        master_port_info->clock_rate, 
     207                                        master_port_info->channel_count, 
     208                                        master_port_info->samples_per_frame, 
     209                                        master_port_info->bits_per_sample,  
     210                                        0,      /* options */ 
     211                                        &conf->snd_dev_port); 
    220212 
    221213        } else { 
    222             status = pjmedia_snd_port_create( pool, -1, -1, conf->clock_rate,  
    223                                               conf->channel_count,  
    224                                               conf->samples_per_frame, 
    225                                               conf->bits_per_sample, 
    226                                               0,    /* Options */ 
    227                                               &conf->snd_dev_port); 
    228  
     214            status = pjmedia_snd_port_create(  
     215                                        pool, -1, -1,  
     216                                        master_port_info->clock_rate,  
     217                                        master_port_info->channel_count,  
     218                                        master_port_info->samples_per_frame, 
     219                                        master_port_info->bits_per_sample, 
     220                                        0,    /* Options */ 
     221                                        &conf->snd_dev_port); 
    229222        } 
    230223 
     
    246239 
    247240     /* Add the port to the bridge */ 
     241    conf_port->slot = 0; 
    248242    conf->ports[0] = conf_port; 
    249243    conf->port_cnt++; 
     
    286280    conf->options = options; 
    287281    conf->max_ports = max_ports; 
    288     conf->clock_rate = clock_rate; 
    289     conf->channel_count = channel_count; 
    290     conf->samples_per_frame = samples_per_frame; 
    291     conf->bits_per_sample = bits_per_sample; 
    292  
    293282     
    294283    /* Create and initialize the master port interface. */ 
     
    425414    conf->ports[0]->name.slen = len; 
    426415 
    427     if (conf->master_port) 
    428         conf->master_port->info.name = conf->ports[0]->name; 
     416    conf->master_port->info.name = conf->ports[0]->name; 
    429417 
    430418    return PJ_SUCCESS; 
     
    445433 
    446434    PJ_ASSERT_RETURN(conf && pool && strm_port, PJ_EINVAL); 
     435    /* 
    447436    PJ_ASSERT_RETURN(conf->clock_rate == strm_port->info.clock_rate,  
    448437                     PJMEDIA_ENCCLOCKRATE); 
     
    451440    PJ_ASSERT_RETURN(conf->bits_per_sample == strm_port->info.bits_per_sample, 
    452441                     PJMEDIA_ENCBITS); 
     442    */ 
    453443 
    454444    /* Port's samples per frame should be equal to or multiplication of  
    455445     * conference's samples per frame. 
    456446     */ 
     447    /* 
     448    Not sure if this is needed! 
    457449    PJ_ASSERT_RETURN((conf->samples_per_frame % 
    458450                     strm_port->info.samples_per_frame==0) || 
     
    460452                     conf->samples_per_frame==0), 
    461453                     PJMEDIA_ENCSAMPLESPFRAME); 
     454    */ 
    462455 
    463456    /* If port_name is not specified, use the port's name */ 
     
    489482 
    490483    /* Put the port. */ 
     484    conf_port->slot = index; 
    491485    conf->ports[index] = conf_port; 
    492486    conf->port_cnt++; 
     
    589583    dst_port = conf->ports[sink_slot]; 
    590584 
     585    /* Source and sink ptime must be equal or a multiplication factor. */ 
     586    if ((src_port->info->samples_per_frame %  
     587         dst_port->info->samples_per_frame != 0) && 
     588        (dst_port->info->samples_per_frame %  
     589         src_port->info->samples_per_frame != 0)) 
     590    { 
     591        pj_mutex_unlock(conf->mutex); 
     592        return PJMEDIA_ENCSAMPLESPFRAME; 
     593    } 
     594     
    591595    /* Check if source and sink has compatible format */ 
    592596    if (src_slot != 0 && sink_slot != 0 &&  
     
    678682        --src_port->listener_cnt; 
    679683        --dst_port->transmitter_cnt; 
     684         
     685        /* Clean up sink TX buffer. */ 
     686        pj_bzero(dst_port->tx_buf, sizeof(pjmedia_frame_ext)); 
    680687 
    681688        PJ_LOG(4,(THIS_FILE, 
     
    777784        pj_assert(conf->connect_cnt > 0); 
    778785        --conf->connect_cnt; 
     786 
     787        /* Clean up TX buffer. */ 
     788        pj_bzero(dst_port->tx_buf, sizeof(pjmedia_frame_ext)); 
    779789    } 
    780790 
     
    842852    info->listener_cnt = conf_port->listener_cnt; 
    843853    info->listener_slots = conf_port->listener_slots; 
    844     info->clock_rate = conf_port->clock_rate; 
    845     info->channel_count = conf_port->channel_count; 
    846     info->samples_per_frame = conf_port->samples_per_frame; 
    847     info->bits_per_sample = conf->bits_per_sample; 
    848     info->format = slot? conf_port->port->info.format :  
    849                          conf->master_port->info.format; 
     854    info->clock_rate = conf_port->info->clock_rate; 
     855    info->channel_count = conf_port->info->channel_count; 
     856    info->samples_per_frame = conf_port->info->samples_per_frame; 
     857    info->bits_per_sample = conf_port->info->bits_per_sample; 
     858    info->format = conf_port->port->info.format; 
    850859 
    851860    return PJ_SUCCESS; 
     
    9911000             * samples per frame. 
    9921001             */ 
    993             if (f_dst->samples_cnt == cport_dst->samples_per_frame) 
     1002            if (f_dst->samples_cnt == cport_dst->info->samples_per_frame) 
    9941003            { 
    995                 if (cport_dst->port) { 
     1004                if (cport_dst->slot) { 
    9961005                    pjmedia_port_put_frame(cport_dst->port,  
    9971006                                           (pjmedia_frame*)f_dst); 
     
    10041013                /* Update TX timestamp. */ 
    10051014                pj_add_timestamp32(&cport_dst->ts_tx,  
    1006                                    cport_dst->samples_per_frame); 
    1007  
     1015                                   cport_dst->info->samples_per_frame); 
    10081016            } 
    10091017        } 
     
    10201028            /* Copy frame to listener's TX buffer. */ 
    10211029            nsamples_to_copy = f_end - f_start; 
    1022             nsamples_req = cport_dst->samples_per_frame - (frm_dst->size>>1); 
     1030            nsamples_req = cport_dst->info->samples_per_frame -  
     1031                          (frm_dst->size>>1); 
    10231032            if (nsamples_to_copy > nsamples_req) 
    10241033                nsamples_to_copy = nsamples_req; 
     1034 
    10251035            pjmedia_copy_samples((pj_int16_t*)frm_dst->buf + (frm_dst->size>>1), 
    10261036                                 f_start,  
     
    10331043             * samples per frame. 
    10341044             */ 
    1035             if ((frm_dst->size >> 1) == cport_dst->samples_per_frame) 
     1045            if ((frm_dst->size >> 1) == cport_dst->info->samples_per_frame) 
    10361046            { 
    1037                 if (cport_dst->port) { 
     1047                if (cport_dst->slot) { 
    10381048                    pjmedia_port_put_frame(cport_dst->port, frm_dst); 
    10391049 
     
    10441054                /* Update TX timestamp. */ 
    10451055                pj_add_timestamp32(&cport_dst->ts_tx,  
    1046                                    cport_dst->samples_per_frame); 
     1056                                   cport_dst->info->samples_per_frame); 
    10471057            } 
    10481058        } 
     
    10591069            if (frm_dst->size != 0) { 
    10601070                pjmedia_zero_samples((pj_int16_t*)frm_dst->buf, 
    1061                                      cport_dst->samples_per_frame -  
     1071                                     cport_dst->info->samples_per_frame -  
    10621072                                     (frm_dst->size>>1)); 
    10631073 
    10641074                frm_dst->type = PJMEDIA_FRAME_TYPE_AUDIO; 
    1065                 frm_dst->size = cport_dst->samples_per_frame << 1; 
    1066                 if (cport_dst->port) { 
     1075                frm_dst->size = cport_dst->info->samples_per_frame << 1; 
     1076                if (cport_dst->slot) { 
    10671077                    pjmedia_port_put_frame(cport_dst->port, frm_dst); 
    10681078 
     
    10731083                /* Update TX timestamp. */ 
    10741084                pj_add_timestamp32(&cport_dst->ts_tx,  
    1075                                    cport_dst->samples_per_frame); 
     1085                                   cport_dst->info->samples_per_frame); 
    10761086            } 
    10771087        } else { 
     
    10811091                frm_dst->type = PJMEDIA_FRAME_TYPE_EXTENDED; 
    10821092                pjmedia_frame_ext_append_subframe(f_dst, NULL, 0, (pj_uint16_t) 
    1083                                                   (cport_dst->samples_per_frame- 
    1084                                                    f_dst->samples_cnt)); 
    1085                 if (cport_dst->port) { 
     1093                    (cport_dst->info->samples_per_frame - f_dst->samples_cnt)); 
     1094                if (cport_dst->slot) { 
    10861095                    pjmedia_port_put_frame(cport_dst->port, frm_dst); 
    10871096 
     
    10931102                /* Update TX timestamp. */ 
    10941103                pj_add_timestamp32(&cport_dst->ts_tx,  
    1095                                    cport_dst->samples_per_frame); 
     1104                                   cport_dst->info->samples_per_frame); 
    10961105            } 
    10971106        } 
     
    11031112            frm_dst->type = PJMEDIA_FRAME_TYPE_NONE; 
    11041113            frm_dst->timestamp = cport_dst->ts_tx; 
    1105             if (cport_dst->port) 
     1114            if (cport_dst->slot) 
    11061115                pjmedia_port_put_frame(cport_dst->port, frm_dst); 
    11071116 
    11081117            /* Update TX timestamp. */ 
    1109             pj_add_timestamp32(&cport_dst->ts_tx, cport_dst->samples_per_frame); 
     1118            pj_add_timestamp32(&cport_dst->ts_tx, cport_dst->info->samples_per_frame); 
    11101119        } 
    11111120    } 
     
    11441153 
    11451154        /* Update clock of the port. */ 
    1146         pj_add_timestamp32(&cport->ts_clock, conf->samples_per_frame); 
     1155        pj_add_timestamp32(&cport->ts_clock,  
     1156                           conf->master_port->info.samples_per_frame); 
    11471157 
    11481158        /* Skip if we're not allowed to receive from this port or  
     
    11661176            pj_int32_t level; 
    11671177 
    1168             pj_add_timestamp32(&cport->ts_rx, cport->samples_per_frame); 
     1178            pj_add_timestamp32(&cport->ts_rx, cport->info->samples_per_frame); 
    11691179             
    11701180            f->buf = &conf->buf[sizeof(pjmedia_frame)]; 
     
    12001210                if (listener->tx_setting == PJMEDIA_PORT_DISABLE) { 
    12011211                    pj_add_timestamp32(&listener->ts_tx,  
    1202                                        listener->samples_per_frame); 
     1212                                       listener->info->samples_per_frame); 
    12031213                    listener->tx_level = 0; 
    12041214                    continue; 
     
    12501260 
    12511261                    pjmedia_port_put_frame(cport->port, &tmp_f); 
    1252                     pj_add_timestamp32(&cport->ts_tx, cport->samples_per_frame); 
     1262                    pj_add_timestamp32(&cport->ts_tx, cport->info->samples_per_frame); 
    12531263                } 
    12541264            } 
     
    12691279            pj_uint16_t samples_per_subframe; 
    12701280             
    1271             if (f_src_->samples_cnt < this_cport->samples_per_frame) { 
     1281            if (f_src_->samples_cnt < this_cport->info->samples_per_frame) { 
    12721282                pj_bzero(this_cport->tx_buf, sizeof(pjmedia_frame_ext)); 
    12731283                frame->type = PJMEDIA_FRAME_TYPE_NONE; 
     
    12811291 
    12821292 
    1283             while (f_dst->samples_cnt < this_cport->samples_per_frame) { 
     1293            while (f_dst->samples_cnt < this_cport->info->samples_per_frame) { 
    12841294                sf = pjmedia_frame_ext_get_subframe(f_src_, i++); 
    12851295                pj_assert(sf); 
     
    12921302 
    12931303        } else if (f_src->type == PJMEDIA_FRAME_TYPE_AUDIO) { 
    1294             if ((f_src->size>>1) < this_cport->samples_per_frame) { 
     1304            if ((f_src->size>>1) < this_cport->info->samples_per_frame) { 
    12951305                pj_bzero(this_cport->tx_buf, sizeof(pjmedia_frame_ext)); 
    12961306                frame->type = PJMEDIA_FRAME_TYPE_NONE; 
     
    13001310            pjmedia_copy_samples((pj_int16_t*)frame->buf,  
    13011311                                 (pj_int16_t*)f_src->buf,  
    1302                                  this_cport->samples_per_frame); 
    1303             frame->size = this_cport->samples_per_frame << 1; 
     1312                                 this_cport->info->samples_per_frame); 
     1313            frame->size = this_cport->info->samples_per_frame << 1; 
    13041314 
    13051315            /* Shift left TX buffer. */ 
     
    13081318                pjmedia_move_samples((pj_int16_t*)f_src->buf, 
    13091319                                     (pj_int16_t*)f_src->buf +  
    1310                                      this_cport->samples_per_frame, 
     1320                                     this_cport->info->samples_per_frame, 
    13111321                                     f_src->size >> 1); 
    13121322        } else { /* PJMEDIA_FRAME_TYPE_NONE */ 
     
    13341344    pj_int32_t level; 
    13351345 
    1336     pj_add_timestamp32(&cport->ts_rx, cport->samples_per_frame); 
     1346    pj_add_timestamp32(&cport->ts_rx, cport->info->samples_per_frame); 
    13371347     
    13381348    /* Skip if this port is muted/disabled. */ 
     
    13731383        if (listener->tx_setting == PJMEDIA_PORT_DISABLE) { 
    13741384            pj_add_timestamp32(&listener->ts_tx,  
    1375                                listener->samples_per_frame); 
     1385                               listener->info->samples_per_frame); 
    13761386            listener->tx_level = 0; 
    13771387            continue; 
     
    13811391        if (listener == cport) { 
    13821392            pj_add_timestamp32(&listener->ts_tx,  
    1383                                listener->samples_per_frame); 
     1393                               listener->info->samples_per_frame); 
    13841394            listener->tx_level = 0; 
    13851395            continue; 
Note: See TracChangeset for help on using the changeset viewer.