Ignore:
Timestamp:
Mar 4, 2008 3:37:45 PM (14 years ago)
Author:
bennylp
Message:

More ticket #438: improve docs, added channel_count in wsola, etc.

File:
1 edited

Legend:

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

    r1840 r1844  
    4949#define OP_GET              (-1) 
    5050 
    51 /* Media flow directions */ 
     51 
     52/*  
     53 * Media flow directions: 
     54 * 
     55 *             put_frame() +-----+ 
     56 *  UPSTREAM  ------------>|split|<--> DOWNSTREAM 
     57 *            <------------|comb | 
     58 *             get_frame() +-----+ 
     59 * 
     60 */ 
    5261enum sc_dir 
    5362{ 
    54     /* This is the direction from the splitcomb to the downstream 
    55      * port(s), or when put_frame() is called to the splitcomb. 
     63    /* This is the media direction from the splitcomb to the  
     64     * downstream port(s), which happens when: 
     65     *  - put_frame() is called to the splitcomb 
     66     *  - get_frame() is called to the reverse channel port. 
    5667     */ 
    5768    DIR_DOWNSTREAM, 
    5869 
    59     /* This is the direction from the downstream port to the splitcomb, 
    60      * or when get_frame() is called to the splitcomb. 
     70    /* This is the media direction from the downstream port to  
     71     * the splitcomb, which happens when: 
     72     *  - get_frame() is called to the splitcomb 
     73     *  - put_frame() is called to the reverse channel port. 
    6174     */ 
    6275    DIR_UPSTREAM 
    6376}; 
    6477 
    65  
    66  
    67 #if 0 
    68 #   define TRACE_UP_(x) PJ_LOG(5,x) 
    69 #   define TRACE_DN_(x) PJ_LOG(5,x) 
    70 #else 
    71 #   define TRACE_UP_(x) 
    72 #   define TRACE_DN_(x) 
    73 #endif 
    7478 
    7579 
     
    107111    unsigned         ch_num; 
    108112 
    109     /* Maximum burst before media flow is suspended */ 
     113    /* Maximum burst before media flow is suspended. 
     114     * With reverse port, it's possible that either end of the  
     115     * port doesn't actually process the media flow (meaning, it 
     116     * stops calling get_frame()/put_frame()). When this happens, 
     117     * the other end will encounter excessive underflow or overflow, 
     118     * depending on which direction is not actively processed by 
     119     * the stopping end. 
     120     * 
     121     * To avoid excessive underflow/overflow, the media flow will 
     122     * be suspended once underflow/overflow goes over this max_burst 
     123     * limit. 
     124     */ 
    110125    int              max_burst; 
    111126 
    112     /* Maximum NULL frames received before media flow is suspended. */ 
     127    /* When the media interface port of the splitcomb or the reverse 
     128     * channel port is registered to conference bridge, the bridge 
     129     * will transmit NULL frames to the media port when the media 
     130     * port is not receiving any audio from other slots (for example, 
     131     * when no other slots are connected to the media port). 
     132     * 
     133     * When this happens, we will generate zero frame to our buffer, 
     134     * to avoid underflow/overflow. But after too many NULL frames 
     135     * are received, we will pause the media flow instead, to save 
     136     * some processing. 
     137     * 
     138     * This value controls how many NULL frames can be received 
     139     * before we suspend media flow for a particular direction. 
     140     */ 
    113141    unsigned         max_null_frames; 
    114142 
    115     /* A reverse port need a temporary buffer to store frame 
     143    /* A reverse port need a temporary buffer to store frames 
    116144     * (because of the different phase, see splitcomb.h for details).  
    117145     * Since we can not expect get_frame() and put_frame() to be 
     
    314342    port->on_destroy = &rport_on_destroy; 
    315343 
    316  
     344    /* Buffer settings */ 
    317345    buf_cnt = options & 0xFF; 
    318346    if (buf_cnt == 0) 
     
    323351 
    324352    /* Create downstream/put buffers */ 
    325     status = pjmedia_delay_buf_create(pool, "scomb-down", 
     353    status = pjmedia_delay_buf_create(pool, "scombdb-dn", 
    326354                                      port->info.clock_rate, 
    327355                                      port->info.samples_per_frame, 
     
    333361 
    334362    /* Create upstream/get buffers */ 
    335     status = pjmedia_delay_buf_create(pool, "scomb-up", 
     363    status = pjmedia_delay_buf_create(pool, "scombdb-up", 
    336364                                      port->info.clock_rate, 
    337365                                      port->info.samples_per_frame, 
     
    446474 
    447475/* 
    448  * "Write" a multichannel frame. This would split the multichannel frame 
    449  * into individual mono channel, and write it to the appropriate port. 
     476 * "Write" a multichannel frame downstream. This would split  
     477 * the multichannel frame into individual mono channel, and write  
     478 * it to the appropriate port. 
    450479 */ 
    451480static pj_status_t put_frame(pjmedia_port *this_port,  
     
    466495            } else { 
    467496                struct reverse_port *rport = (struct reverse_port*)port; 
    468  
    469                 /* Write zero port to delaybuf so that it doesn't underflow.  
    470                  * If we don't do this, get_frame() on this direction will 
    471                  * cause delaybuf to generate missing frame and the last 
    472                  * frame transmitted to delaybuf will be replayed multiple 
    473                  * times, which doesn't sound good. 
    474                  */ 
    475497 
    476498                /* Update the number of NULL frames received. Once we have too 
     
    490512                } 
    491513 
     514                /* Write zero port to delaybuf so that it doesn't underflow.  
     515                 * If we don't do this, get_frame() on this direction will 
     516                 * cause delaybuf to generate missing frame and the last 
     517                 * frame transmitted to delaybuf will be replayed multiple 
     518                 * times, which doesn't sound good. 
     519                 */ 
     520 
    492521                /* Update rport state. */ 
    493522                op_update(rport, DIR_DOWNSTREAM, OP_PUT); 
     
    498527 
    499528                /* Generate zero frame. */ 
    500                 pjmedia_zero_samples(rport->tmp_up_buf,  
     529                pjmedia_zero_samples(sc->put_buf,  
    501530                                     this_port->info.samples_per_frame); 
    502531 
    503532                /* Put frame to delay buffer */ 
    504533                pjmedia_delay_buf_put(rport->buf[DIR_DOWNSTREAM].dbuf, 
    505                                       rport->tmp_up_buf); 
     534                                      sc->put_buf); 
    506535 
    507536            } 
     
    566595 
    567596/* 
    568  * Get a multichannel frame. 
     597 * Get a multichannel frame upstream. 
    569598 * This will get mono channel frame from each port and put the 
    570599 * mono frame into the multichannel frame. 
     
    617646            } else { 
    618647                pjmedia_zero_samples(sc->get_buf,  
    619                                       rport->base.info.samples_per_frame); 
     648                                     port->info.samples_per_frame); 
    620649            } 
    621650 
     
    628657                         this_port->info.channel_count, 
    629658                         this_port->info.samples_per_frame); 
    630  
    631  
    632659 
    633660        has_frame = PJ_TRUE; 
     
    647674static pj_status_t on_destroy(pjmedia_port *this_port) 
    648675{ 
    649     /* Nothing to do */ 
     676    /* Nothing to do for the splitcomb 
     677     * Reverse ports must be destroyed separately. 
     678     */ 
    650679    PJ_UNUSED_ARG(this_port); 
    651680 
     
    655684 
    656685/* 
    657  * Get a mono frame from a reversed phase channel. 
     686 * Put a frame in the reverse port (upstream direction). This frame 
     687 * will be picked up by get_frame() above. 
    658688 */ 
    659689static pj_status_t rport_put_frame(pjmedia_port *this_port,  
     
    666696    /* Handle NULL frame */ 
    667697    if (frame->type != PJMEDIA_FRAME_TYPE_AUDIO) { 
    668         TRACE_UP_((THIS_FILE, "Upstream write %d null samples at buf pos %d", 
    669                    this_port->info.samples_per_frame, rport->up_write_pos)); 
    670  
    671         /* Write zero port to delaybuf so that it doesn't underflow.  
    672          * If we don't do this, get_frame() on this direction will 
    673          * cause delaybuf to generate missing frame and the last 
    674          * frame transmitted to delaybuf will be replayed multiple 
    675          * times, which doesn't sound good. 
    676          */ 
    677  
    678698        /* Update the number of NULL frames received. Once we have too 
    679699         * many of this, we'll stop calling op_update() to let the 
     
    688708        } 
    689709 
     710        /* Write zero port to delaybuf so that it doesn't underflow.  
     711         * If we don't do this, get_frame() on this direction will 
     712         * cause delaybuf to generate missing frame and the last 
     713         * frame transmitted to delaybuf will be replayed multiple 
     714         * times, which doesn't sound good. 
     715         */ 
     716 
    690717        /* Update rport state. */ 
    691718        op_update(rport, DIR_UPSTREAM, OP_PUT); 
     
    730757 
    731758 
    732 /* 
    733  * Get a mono frame from a reversed phase channel. 
     759/* Get a mono frame from a reversed phase channel (downstream direction). 
     760 * The frame is put by put_frame() call to the splitcomb. 
    734761 */ 
    735762static pj_status_t rport_get_frame(pjmedia_port *this_port,  
Note: See TracChangeset for help on using the changeset viewer.