Changeset 5717
- Timestamp:
- Dec 19, 2017 1:45:37 AM (7 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip-apps/src/samples/pjsua2_demo.cpp
r5650 r5717 226 226 std::cout << "*** PJSUA2 STARTED ***" << std::endl; 227 227 228 /* Use Null Audio Device as main media clock. This is useful for improving 229 * media clock (see also https://trac.pjsip.org/repos/wiki/FAQ#tx-timing) 230 * especially when sound device clock is jittery. 231 */ 232 ep.audDevManager().setNullDev(); 233 234 /* And install sound device using Extra Audio Device */ 235 ExtraAudioDevice auddev2(-1, -1); 236 try { 237 auddev2.open(); 238 } catch (...) { 239 std::cout << "Extra sound device failed" << std::endl; 240 } 241 228 242 // Create player and recorder 229 243 { … … 234 248 amr.createRecorder("recorder_test_output.wav"); 235 249 236 amp.startTransmit(ep.audDevManager().getPlaybackDevMedia());237 250 amp.startTransmit(amr); 251 if (auddev2.isOpened()) 252 amp.startTransmit(auddev2); 238 253 239 254 pj_thread_sleep(5000); … … 332 347 ep.libCreate(); 333 348 334 mainProg 4(ep);349 mainProg3(ep); 335 350 ret = PJ_SUCCESS; 336 351 } catch (Error & err) { -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
r5712 r5717 7045 7045 7046 7046 7047 /** 7048 * Opaque type of extra sound device, an additional sound device 7049 * beside the primary sound device (the one instantiated via 7050 * pjsua_set_snd_dev() or pjsua_set_snd_dev2()). This sound device is 7051 * also registered to conference bridge so it can be used as a normal 7052 * conference bridge port, e.g: connect it to/from other ports, 7053 * adjust/check audio level, etc. The conference bridge port ID can be 7054 * queried using pjsua_ext_snd_dev_get_conf_port(). 7055 * 7056 * Application may also use this API to improve media clock. Normally 7057 * media clock is driven by sound device in master port, but unfortunately 7058 * some sound devices may produce jittery clock. To improve media clock, 7059 * application can install Null Sound Device (i.e: using 7060 * pjsua_set_null_snd_dev()), which will act as a master port, and instantiate 7061 * the sound device as extra sound device. But note that extra sound device 7062 * will not have auto-close upon idle feature. 7063 */ 7064 typedef struct pjsua_ext_snd_dev pjsua_ext_snd_dev; 7065 7066 7067 /** 7068 * Create an extra sound device and register it to conference bridge. 7069 * 7070 * @param snd_param Sound device port param. 7071 * @param p_snd The extra sound device instance. 7072 * 7073 * @return PJ_SUCCESS on success or the appropriate error code. 7074 */ 7075 PJ_DECL(pj_status_t) pjsua_ext_snd_dev_create(pjmedia_snd_port_param *param, 7076 pjsua_ext_snd_dev **p_snd); 7077 7078 7079 /** 7080 * Destroy an extra sound device and unregister it from conference bridge. 7081 * 7082 * @param p_snd The extra sound device instance. 7083 * 7084 * @return PJ_SUCCESS on success or the appropriate error code. 7085 */ 7086 PJ_DECL(pj_status_t) pjsua_ext_snd_dev_destroy(pjsua_ext_snd_dev *snd); 7087 7088 7089 /** 7090 * Get sound port instance of an extra sound device. 7091 * 7092 * @param snd The extra sound device instance. 7093 * 7094 * @return The sound port instance. 7095 */ 7096 PJ_DECL(pjmedia_snd_port*) pjsua_ext_snd_dev_get_snd_port( 7097 pjsua_ext_snd_dev *snd); 7098 7099 /** 7100 * Get conference port ID of an extra sound device. 7101 * 7102 * @param snd The extra sound device instance. 7103 * 7104 * @return The conference port ID. 7105 */ 7106 PJ_DECL(pjsua_conf_port_id) pjsua_ext_snd_dev_get_conf_port( 7107 pjsua_ext_snd_dev *snd); 7108 7109 7047 7110 /***************************************************************************** 7048 7111 * Codecs. -
pjproject/trunk/pjsip/include/pjsua2/media.hpp
r5645 r5717 1350 1350 1351 1351 1352 /** 1353 * Extra audio device. This class allows application to have multiple 1354 * sound device instances active concurrently. Application may also use 1355 * this class to improve media clock. Normally media clock is driven by 1356 * sound device in master port, but unfortunately some sound devices may 1357 * produce jittery clock. To improve media clock, application can install 1358 * Null Sound Device (i.e: using AudDevManager::setNullDev()), which will 1359 * act as a master port, and install the sound device as extra sound device. 1360 * Note that extra sound device will not have auto-close upon idle feature. 1361 */ 1362 class ExtraAudioDevice : public AudioMedia 1363 { 1364 public: 1365 /** 1366 * Constructor 1367 * 1368 * @param playdev Playback device ID. 1369 * @param recdev Record device ID. 1370 */ 1371 ExtraAudioDevice(int playdev, int recdev); 1372 1373 /** 1374 * Destructor 1375 */ 1376 virtual ~ExtraAudioDevice(); 1377 1378 /** 1379 * Open the audio device using format (e.g.: clock rate, channel count, 1380 * samples per frame) matched to the conference bridge's format. 1381 */ 1382 void open(); 1383 1384 /** 1385 * Close the audio device. 1386 */ 1387 void close(); 1388 1389 /** 1390 * Is the extra audio device opened? 1391 * 1392 * @return 'true' if it is opened. 1393 */ 1394 bool isOpened(); 1395 1396 protected: 1397 int playDev; 1398 int recDev; 1399 void *ext_snd_dev; 1400 }; 1401 1402 1352 1403 /************************************************************************* 1353 1404 * Video media -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_aud.c
r5713 r5717 2310 2310 } 2311 2311 2312 2313 /* 2314 * Extra sound device 2315 */ 2316 struct pjsua_ext_snd_dev 2317 { 2318 pj_pool_t *pool; 2319 pjmedia_port *splitcomb; 2320 pjmedia_port *rev_port; 2321 pjmedia_snd_port *snd_port; 2322 pjsua_conf_port_id port_id; 2323 }; 2324 2325 2326 /* 2327 * Create an extra sound device and register it to conference bridge. 2328 */ 2329 PJ_DEF(pj_status_t) pjsua_ext_snd_dev_create( pjmedia_snd_port_param *param, 2330 pjsua_ext_snd_dev **p_snd) 2331 { 2332 pjsua_ext_snd_dev *snd = NULL; 2333 pj_pool_t *pool; 2334 pj_status_t status; 2335 2336 PJ_ASSERT_RETURN(param && p_snd, PJ_EINVAL); 2337 2338 pool = pjsua_pool_create("extsnd%p", 512, 512); 2339 if (!pool) 2340 return PJ_ENOMEM; 2341 2342 snd = PJ_POOL_ZALLOC_T(pool, pjsua_ext_snd_dev); 2343 if (!snd) { 2344 pj_pool_release(pool); 2345 return PJ_ENOMEM; 2346 } 2347 2348 snd->pool = pool; 2349 snd->port_id = PJSUA_INVALID_ID; 2350 2351 /* Create mono splitter/combiner */ 2352 status = pjmedia_splitcomb_create( 2353 pool, 2354 param->base.clock_rate, 2355 param->base.channel_count, 2356 param->base.samples_per_frame, 2357 param->base.bits_per_sample, 2358 0, /* options */ 2359 &snd->splitcomb); 2360 if (status != PJ_SUCCESS) 2361 goto on_return; 2362 2363 /* Create reverse channel */ 2364 status = pjmedia_splitcomb_create_rev_channel( 2365 pool, 2366 snd->splitcomb, 2367 0 /* channel #1 */, 2368 0 /* options */, 2369 &snd->rev_port); 2370 if (status != PJ_SUCCESS) 2371 goto on_return; 2372 2373 /* And register it to conference bridge */ 2374 status = pjsua_conf_add_port(pool, snd->rev_port, &snd->port_id); 2375 if (status != PJ_SUCCESS) 2376 goto on_return; 2377 2378 /* Create sound device */ 2379 status = pjmedia_snd_port_create2(pool, param, &snd->snd_port); 2380 if (status != PJ_SUCCESS) 2381 goto on_return; 2382 2383 /* Connect the splitter to the sound device */ 2384 status = pjmedia_snd_port_connect(snd->snd_port, snd->splitcomb); 2385 if (status != PJ_SUCCESS) 2386 goto on_return; 2387 2388 /* Finally */ 2389 *p_snd = snd; 2390 PJ_LOG(4,(THIS_FILE, "Extra sound device created")); 2391 2392 on_return: 2393 if (status != PJ_SUCCESS) { 2394 PJ_LOG(3,(THIS_FILE, "Failed creating extra sound device")); 2395 pjsua_ext_snd_dev_destroy(snd); 2396 } 2397 2398 return status; 2399 } 2400 2401 2402 /* 2403 * Destroy an extra sound device and unregister it from conference bridge. 2404 */ 2405 PJ_DEF(pj_status_t) pjsua_ext_snd_dev_destroy(pjsua_ext_snd_dev *snd) 2406 { 2407 PJ_ASSERT_RETURN(snd, PJ_EINVAL); 2408 2409 /* Unregister from the conference bridge */ 2410 if (snd->port_id != PJSUA_INVALID_ID) { 2411 pjsua_conf_remove_port(snd->port_id); 2412 snd->port_id = PJSUA_INVALID_ID; 2413 } 2414 2415 /* Destroy all components */ 2416 if (snd->snd_port) { 2417 pjmedia_snd_port_disconnect(snd->snd_port); 2418 pjmedia_snd_port_destroy(snd->snd_port); 2419 snd->snd_port = NULL; 2420 } 2421 if (snd->rev_port) { 2422 pjmedia_port_destroy(snd->rev_port); 2423 snd->rev_port = NULL; 2424 } 2425 if (snd->splitcomb) { 2426 pjmedia_port_destroy(snd->splitcomb); 2427 snd->splitcomb = NULL; 2428 } 2429 2430 /* Finally */ 2431 pj_pool_safe_release(&snd->pool); 2432 2433 PJ_LOG(4,(THIS_FILE, "Extra sound device destroyed")); 2434 2435 return PJ_SUCCESS; 2436 } 2437 2438 2439 /* 2440 * Get sound port instance of an extra sound device. 2441 */ 2442 PJ_DEF(pjmedia_snd_port*) pjsua_ext_snd_dev_get_snd_port( 2443 pjsua_ext_snd_dev *snd) 2444 { 2445 PJ_ASSERT_RETURN(snd, NULL); 2446 return snd->snd_port; 2447 } 2448 2449 /* 2450 * Get conference port ID of an extra sound device. 2451 */ 2452 PJ_DEF(pjsua_conf_port_id) pjsua_ext_snd_dev_get_conf_port( 2453 pjsua_ext_snd_dev *snd) 2454 { 2455 PJ_ASSERT_RETURN(snd, PJSUA_INVALID_ID); 2456 return snd->port_id; 2457 } 2458 2459 2312 2460 #endif /* PJSUA_MEDIA_HAS_PJMEDIA */ -
pjproject/trunk/pjsip/src/pjsua2/media.cpp
r5654 r5717 1029 1029 } 1030 1030 1031 1032 /////////////////////////////////////////////////////////////////////////////// 1033 ExtraAudioDevice::ExtraAudioDevice (int playdev, int recdev) : 1034 playDev(playdev), recDev(recdev), ext_snd_dev(NULL) 1035 { 1036 } 1037 1038 ExtraAudioDevice::~ExtraAudioDevice() 1039 { 1040 close(); 1041 } 1042 1043 void ExtraAudioDevice::open() 1044 { 1045 pj_status_t status; 1046 1047 /* Opened already? */ 1048 if (isOpened()) 1049 return; 1050 1051 /* Get port info of conference bridge master port */ 1052 pjsua_conf_port_info master_info; 1053 status = pjsua_conf_get_port_info(0, &master_info); 1054 PJSUA2_CHECK_RAISE_ERROR(status); 1055 1056 /* Generate sound device port param */ 1057 pjmedia_snd_port_param param; 1058 pjmedia_snd_port_param_default(¶m); 1059 1060 status = pjmedia_aud_dev_default_param(recDev, ¶m.base); 1061 PJSUA2_CHECK_RAISE_ERROR(status); 1062 1063 param.base.dir = PJMEDIA_DIR_CAPTURE_PLAYBACK; 1064 param.base.play_id = playDev; 1065 param.base.rec_id = recDev; 1066 param.base.clock_rate = master_info.clock_rate; 1067 param.base.channel_count = master_info.channel_count; 1068 param.base.samples_per_frame = master_info.samples_per_frame; 1069 param.base.bits_per_sample = master_info.bits_per_sample; 1070 1071 /* Create the extra sound device */ 1072 pjsua_ext_snd_dev *snd_dev; 1073 status = pjsua_ext_snd_dev_create(¶m, &snd_dev); 1074 PJSUA2_CHECK_RAISE_ERROR(status); 1075 ext_snd_dev = snd_dev; 1076 1077 /* Register to the conference bridge */ 1078 registerMediaPort(NULL); 1079 id = pjsua_ext_snd_dev_get_conf_port(snd_dev); 1080 } 1081 1082 bool ExtraAudioDevice::isOpened() 1083 { 1084 return (id != PJSUA_INVALID_ID); 1085 } 1086 1087 void ExtraAudioDevice::close() 1088 { 1089 /* Unregister from the conference bridge */ 1090 id = PJSUA_INVALID_ID; 1091 unregisterMediaPort(); 1092 1093 /* Destroy the extra sound device */ 1094 if (ext_snd_dev) { 1095 pjsua_ext_snd_dev *snd_dev = (pjsua_ext_snd_dev*)ext_snd_dev; 1096 ext_snd_dev = NULL; 1097 pjsua_ext_snd_dev_destroy(snd_dev); 1098 } 1099 } 1100 1031 1101 /////////////////////////////////////////////////////////////////////////////// 1032 1102 VideoWindow::VideoWindow(pjsua_vid_win_id win_id)
Note: See TracChangeset
for help on using the changeset viewer.