Ignore:
Timestamp:
Feb 18, 2009 2:28:49 PM (15 years ago)
Author:
nanang
Message:
  • Added APS-direct sound device management into pjsua-lib (and removed it from apps).
  • Fixed bug in conf_switch.c to always update ts_rx (even if port is not transmitting).
  • Minor updates: 'fmt_id' to 'id', added transmitter_Cnt in conf port info, explicit mapping in Symbian audio APS impl from pjmedia_format_id to Symbian APS fourcc.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/aps-direct/pjsip/src/pjsua-lib/pjsua_media.c

    r2438 r2460  
    15101510} 
    15111511 
     1512#if PJMEDIA_CONF_USE_SWITCH_BOARD 
     1513 
     1514/* 
     1515 * Open sound device with extended setting. 
     1516 */ 
     1517static pj_status_t open_snd_dev_ext( int capture_dev, 
     1518                                     int playback_dev, 
     1519                                     unsigned clock_rate, 
     1520                                     unsigned channel_count, 
     1521                                     unsigned samples_per_frame, 
     1522                                     const pjmedia_snd_setting *setting) 
     1523{ 
     1524    pjmedia_port *conf_port; 
     1525    pj_status_t status; 
     1526 
     1527    PJ_ASSERT_RETURN(setting, PJ_EINVAL); 
     1528 
     1529    /* Check if NULL sound device is used */ 
     1530    if (NULL_SND_DEV_ID == capture_dev || NULL_SND_DEV_ID == playback_dev) { 
     1531        return pjsua_set_null_snd_dev(); 
     1532    } 
     1533 
     1534    /* Close existing sound port */ 
     1535    close_snd_dev(); 
     1536 
     1537    /* Create memory pool for sound device. */ 
     1538    pjsua_var.snd_pool = pjsua_pool_create("pjsua_snd", 4000, 4000); 
     1539    PJ_ASSERT_RETURN(pjsua_var.snd_pool, PJ_ENOMEM); 
     1540 
     1541 
     1542    /* Get the port0 of the conference bridge. */ 
     1543    conf_port = pjmedia_conf_get_master_port(pjsua_var.mconf); 
     1544    pj_assert(conf_port != NULL); 
     1545 
     1546    PJ_LOG(4,(THIS_FILE, "Opening sound device @%d/%d/%s", 
     1547              clock_rate, channel_count, 
     1548              (setting->format.id==PJMEDIA_FORMAT_L16?"raw":"encoded"))); 
     1549 
     1550    status = pjmedia_snd_port_create2( pjsua_var.snd_pool,  
     1551                                       PJMEDIA_DIR_CAPTURE_PLAYBACK, 
     1552                                       capture_dev, 
     1553                                       playback_dev,  
     1554                                       clock_rate,  
     1555                                       channel_count, 
     1556                                       samples_per_frame, 
     1557                                       16,  
     1558                                       setting,  
     1559                                       &pjsua_var.snd_port); 
     1560 
     1561    /* Update port 0 info when sound dev opened successfully. */ 
     1562    if (status == PJ_SUCCESS) { 
     1563        conf_port->info.format = setting->format; 
     1564        conf_port->info.clock_rate = clock_rate; 
     1565        conf_port->info.samples_per_frame = samples_per_frame; 
     1566        conf_port->info.channel_count = channel_count; 
     1567        conf_port->info.bits_per_sample = 16; 
     1568    } else { 
     1569        pjsua_perror(THIS_FILE, "Unable to open sound device", status); 
     1570        return status; 
     1571    } 
     1572 
     1573    /* Connect sound port to the bridge */ 
     1574    status = pjmedia_snd_port_connect(pjsua_var.snd_port,         
     1575                                      conf_port );        
     1576    if (status != PJ_SUCCESS) {           
     1577        pjsua_perror(THIS_FILE, "Unable to connect conference port to " 
     1578                                "sound device", status);          
     1579        pjmedia_snd_port_destroy(pjsua_var.snd_port);     
     1580        pjsua_var.snd_port = NULL;        
     1581        return status;    
     1582    } 
     1583 
     1584    /* Save the device IDs */ 
     1585    pjsua_var.cap_dev = capture_dev; 
     1586    pjsua_var.play_dev = playback_dev; 
     1587 
     1588    /* Update sound device name. */ 
     1589    do { 
     1590        const pjmedia_snd_dev_info *play_info; 
     1591        pjmedia_snd_stream *strm; 
     1592        pjmedia_snd_stream_info si; 
     1593        pj_str_t tmp; 
     1594 
     1595        strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port); 
     1596        pjmedia_snd_stream_get_info(strm, &si); 
     1597        play_info = pjmedia_snd_get_dev_info(si.rec_id); 
     1598 
     1599        pjmedia_conf_set_port0_name(pjsua_var.mconf,  
     1600                                    pj_cstr(&tmp, play_info->name)); 
     1601    } while(0); 
     1602 
     1603    return PJ_SUCCESS; 
     1604} 
     1605 
     1606#endif 
     1607 
     1608 
     1609/* Close existing sound device */ 
     1610static void close_snd_dev(void) 
     1611{ 
     1612    /* Close sound device */ 
     1613    if (pjsua_var.snd_port) { 
     1614        pjmedia_snd_dev_info cap_info, play_info; 
     1615        pjmedia_snd_stream *strm; 
     1616        pjmedia_snd_stream_info si; 
     1617 
     1618        strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port); 
     1619        pjmedia_snd_stream_get_info(strm, &si); 
     1620        cap_info = *(pjmedia_snd_get_dev_info(si.rec_id)); 
     1621        play_info = *(pjmedia_snd_get_dev_info(si.play_id)); 
     1622 
     1623        PJ_LOG(4,(THIS_FILE, "Closing %s sound playback device and " 
     1624                             "%s sound capture device", 
     1625                             play_info.name, cap_info.name)); 
     1626 
     1627        pjmedia_snd_port_disconnect(pjsua_var.snd_port); 
     1628        pjmedia_snd_port_destroy(pjsua_var.snd_port); 
     1629        pjsua_var.snd_port = NULL; 
     1630    } 
     1631 
     1632    /* Close null sound device */ 
     1633    if (pjsua_var.null_snd) { 
     1634        PJ_LOG(4,(THIS_FILE, "Closing null sound device..")); 
     1635        pjmedia_master_port_destroy(pjsua_var.null_snd, PJ_FALSE); 
     1636        pjsua_var.null_snd = NULL; 
     1637    } 
     1638 
     1639    if (pjsua_var.snd_pool)  
     1640        pj_pool_release(pjsua_var.snd_pool); 
     1641    pjsua_var.snd_pool = NULL; 
     1642} 
     1643 
    15121644 
    15131645/* 
     
    16251757    } 
    16261758 
     1759#if PJMEDIA_CONF_USE_SWITCH_BOARD 
     1760 
     1761    /* Check if sound device need to be reopened, i.e: its attributes 
     1762     * (format, clock rate, channel count) must match to peer's.  
     1763     * Note that sound device can be reopened only if it doesn't have 
     1764     * any connection. 
     1765     */ 
     1766    do { 
     1767        pjmedia_conf_port_info port0_info; 
     1768        pjmedia_conf_port_info peer_info; 
     1769        unsigned peer_id; 
     1770        pj_bool_t need_reopen = PJ_FALSE; 
     1771        pj_status_t status; 
     1772 
     1773        peer_id = (source!=0)? source : sink; 
     1774        status = pjmedia_conf_get_port_info(pjsua_var.mconf, peer_id,  
     1775                                            &peer_info); 
     1776        pj_assert(status == PJ_SUCCESS); 
     1777 
     1778        status = pjmedia_conf_get_port_info(pjsua_var.mconf, 0, &port0_info); 
     1779        pj_assert(status == PJ_SUCCESS); 
     1780 
     1781        /* Check if sound device is instantiated. */ 
     1782        need_reopen = (pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL &&  
     1783                      !pjsua_var.no_snd); 
     1784 
     1785        /* Check if sound device need to reopen because it needs to modify  
     1786         * settings to match its peer. Sound device must be idle in this case  
     1787         * though. 
     1788         */ 
     1789        if (!need_reopen &&  
     1790            port0_info.listener_cnt==0 && port0_info.transmitter_cnt==0)  
     1791        { 
     1792            need_reopen = (peer_info.format.id != port0_info.format.id || 
     1793                           peer_info.format.bitrate != port0_info.format.bitrate || 
     1794                           peer_info.clock_rate != port0_info.clock_rate || 
     1795                           peer_info.channel_count != port0_info.channel_count); 
     1796        } 
     1797 
     1798        if (need_reopen) { 
     1799            pjmedia_snd_setting setting; 
     1800 
     1801            pj_bzero(&setting, sizeof(setting)); 
     1802            setting.format = peer_info.format; 
     1803            setting.plc = PJ_FALSE; 
     1804            setting.route = PJMEDIA_SND_ROUTE_DEFAULT; 
     1805             
     1806            status = open_snd_dev_ext(pjsua_var.cap_dev, pjsua_var.play_dev, 
     1807                                      peer_info.clock_rate, 
     1808                                      peer_info.channel_count, 
     1809                                      peer_info.samples_per_frame, 
     1810                                      &setting); 
     1811            if (status != PJ_SUCCESS) { 
     1812                pjsua_perror(THIS_FILE, "Error opening sound device", status); 
     1813                return status; 
     1814            } 
     1815        } 
     1816    } while(0); 
     1817 
     1818#else 
     1819 
    16271820    /* Create sound port if none is instantiated */ 
    16281821    if (pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL &&  
     
    16371830        } 
    16381831    } 
     1832 
     1833#endif 
    16391834 
    16401835    return pjmedia_conf_connect_port(pjsua_var.mconf, source, sink, 0); 
     
    21322327    return PJ_SUCCESS; 
    21332328} 
    2134  
    2135  
    2136 /* Close existing sound device */ 
    2137 static void close_snd_dev(void) 
    2138 { 
    2139     /* Close sound device */ 
    2140     if (pjsua_var.snd_port) { 
    2141         const pjmedia_snd_dev_info *cap_info, *play_info; 
    2142  
    2143         cap_info = pjmedia_snd_get_dev_info(pjsua_var.cap_dev); 
    2144         play_info = pjmedia_snd_get_dev_info(pjsua_var.play_dev); 
    2145  
    2146         PJ_LOG(4,(THIS_FILE, "Closing %s sound playback device and " 
    2147                              "%s sound capture device", 
    2148                              play_info->name, cap_info->name)); 
    2149  
    2150         pjmedia_snd_port_disconnect(pjsua_var.snd_port); 
    2151         pjmedia_snd_port_destroy(pjsua_var.snd_port); 
    2152         pjsua_var.snd_port = NULL; 
    2153     } 
    2154  
    2155     /* Close null sound device */ 
    2156     if (pjsua_var.null_snd) { 
    2157         PJ_LOG(4,(THIS_FILE, "Closing null sound device..")); 
    2158         pjmedia_master_port_destroy(pjsua_var.null_snd, PJ_FALSE); 
    2159         pjsua_var.null_snd = NULL; 
    2160     } 
    2161  
    2162     if (pjsua_var.snd_pool)  
    2163         pj_pool_release(pjsua_var.snd_pool); 
    2164     pjsua_var.snd_pool = NULL; 
    2165 } 
    2166  
    21672329/* 
    21682330 * Select or change sound device. Application may call this function at 
     
    24192581 
    24202582 
     2583/* 
     2584 * Set sound device route. 
     2585 */ 
     2586PJ_DEF(pj_status_t) pjsua_set_snd_route(pjmedia_snd_route route) 
     2587{ 
     2588    PJ_UNUSED_ARG(route); 
     2589 
     2590    PJ_TODO(IMPLEMENT_SETTING_AUDIO_ROUTE); 
     2591    return PJ_ENOTSUP; 
     2592} 
     2593 
    24212594/***************************************************************************** 
    24222595 * Codecs. 
Note: See TracChangeset for help on using the changeset viewer.