diff --git a/lib/native/mac/libjnportaudio.jnilib b/lib/native/mac/libjnportaudio.jnilib index 04b39ad9cf52a521d95b15239944539d7df3d081..69126c0e42a705980369a0d137c257cc6b2f048a 100644 Binary files a/lib/native/mac/libjnportaudio.jnilib and b/lib/native/mac/libjnportaudio.jnilib differ diff --git a/src/native/build.xml b/src/native/build.xml index 9eb716062c3c37694dfc7484049fd64bf7615f3c..bf2906d11ff85cd72ba89c863d1b2bc35756f8a9 100644 --- a/src/native/build.xml +++ b/src/native/build.xml @@ -409,8 +409,6 @@ <compilerarg value="x86_64" if="is.running.macos" /> <compilerarg value="-arch" if="is.running.macos" /> <compilerarg value="i386" if="is.running.macos" /> - <compilerarg value="-arch" if="is.running.macos" /> - <compilerarg value="ppc" if="is.running.macos" /> <compilerarg value="-I/System/Library/Frameworks/JavaVM.framework/Headers" if="is.running.macos" /> <linkerarg value="-o" location="end" if="is.running.macos" /> @@ -420,8 +418,6 @@ <linkerarg value="x86_64" if="is.running.macos" /> <linkerarg value="-arch" if="is.running.macos" /> <linkerarg value="i386" if="is.running.macos" /> - <linkerarg value="-arch" if="is.running.macos" /> - <linkerarg value="ppc" if="is.running.macos" /> <linkerarg value="-framework" location="end" if="is.running.macos" /> <linkerarg value="AudioToolbox" location="end" if="is.running.macos" /> <linkerarg value="-framework" location="end" if="is.running.macos" /> @@ -495,8 +491,6 @@ <compilerarg value="x86_64" if="is.running.macos" /> <compilerarg value="-arch" if="is.running.macos" /> <compilerarg value="i386" if="is.running.macos" /> - <compilerarg value="-arch" if="is.running.macos" /> - <compilerarg value="ppc" if="is.running.macos" /> <compilerarg value="-I/System/Library/Frameworks/JavaVM.framework/Headers" if="is.running.macos" /> <linkerarg value="-o" location="end" if="is.running.macos" /> @@ -506,8 +500,6 @@ <linkerarg value="x86_64" if="is.running.macos" /> <linkerarg value="-arch" if="is.running.macos" /> <linkerarg value="i386" if="is.running.macos" /> - <linkerarg value="-arch" if="is.running.macos" /> - <linkerarg value="ppc" if="is.running.macos" /> <linkerarg value="-lspeex" location="end" if="is.running.macos" /> <linkerarg value="-lspeexdsp" location="end" if="is.running.macos" /> diff --git a/src/native/portaudio/README b/src/native/portaudio/README index 12b2ed77dc9e7abe01ab91db52d2a36ecbd621bb..bb9aa066a60c7c6e2c39bf81e895f7e5dbcd1434 100644 --- a/src/native/portaudio/README +++ b/src/native/portaudio/README @@ -1,7 +1,7 @@ 1. portaudio Get portaudio-hotplug branch and apply the portaudio-hotplug-os patch: - $ svn co https://www.portaudio.com/repos/portaudio/branches/hotplug + $ svn co https://subversion.assembla.com/svn/portaudio/portaudio/branches/hotplug/ $ patch -p0 < portaudio-hotplug-os.patch $ autoreconf -i (OS X and Linux only) @@ -27,7 +27,7 @@ - Mac OS X $ export MACOSX_DEPLOYMENT_TARGET=10.4 - $ export CC="gcc -arch i386 -arch ppc -arch x86_64 -mmacosx-version-min=10.4" + $ export CC="gcc -arch i386 -arch x86_64 -mmacosx-version-min=10.4" $ export CPP="gcc -E" $ ./configure --disable-shared --enable-static --with-pic && make diff --git a/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.c b/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.c index 3b274638a9a1b256f734d2ed62662c53543fad7e..133c91a54262f19149655708d4446f1786ad3807 100644 --- a/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.c +++ b/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.c @@ -910,6 +910,62 @@ Java_org_jitsi_impl_neomedia_portaudio_PortAudio_PaDeviceInfo_1getNameBytes return nameBytes; } +JNIEXPORT jbyteArray JNICALL +Java_net_java_sip_communicator_impl_neomedia_portaudio_PortAudio_PaDeviceInfo_1getTransportTypeBytes + (JNIEnv *env, jclass clazz, jlong deviceInfo) +{ + jbyteArray typeBytes = NULL; + if(((PaDeviceInfo *) (intptr_t) deviceInfo)->structVersion >= 3) + { + const char *type + = ((PaDeviceInfo *) (intptr_t) deviceInfo)->transportType; + + if(type != NULL) + { + size_t typeLength = strlen(type); + + typeBytes = (*env)->NewByteArray(env, typeLength); + if (typeBytes && typeLength) + { + (*env)->SetByteArrayRegion( + env, + typeBytes, 0, typeLength, + (jbyte *) type); + } + } + } + + return typeBytes; +} + +JNIEXPORT jbyteArray JNICALL +Java_net_java_sip_communicator_impl_neomedia_portaudio_PortAudio_PaDeviceInfo_1getDeviceUIDBytes + (JNIEnv *env, jclass clazz, jlong deviceInfo) +{ + jbyteArray uidBytes = NULL; + if(((PaDeviceInfo *) (intptr_t) deviceInfo)->structVersion >= 3) + { + const char *uid + = ((PaDeviceInfo *) (intptr_t) deviceInfo)->deviceUID; + + if (uid) + { + size_t uidLength = strlen(uid); + + uidBytes = (*env)->NewByteArray(env, uidLength); + if (uidBytes && uidLength) + { + (*env)->SetByteArrayRegion( + env, + uidBytes, 0, uidLength, + (jbyte *) uid); + } + } + } + + return uidBytes; +} + JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_portaudio_PortAudio_PaHostApiInfo_1getDefaultInputDevice (JNIEnv *env, jclass clazz, jlong hostApi) diff --git a/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.h b/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.h index 61a771bc5bf8b090c097123b0b99a2cd59c5771b..7af57761c3a2694ef3669422f7f14b447ea06395 100644 --- a/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.h +++ b/src/native/portaudio/org_jitsi_impl_neomedia_portaudio_PortAudio.h @@ -229,6 +229,22 @@ JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_portaudio_PortAudio_PaDevice JNIEXPORT jbyteArray JNICALL Java_org_jitsi_impl_neomedia_portaudio_PortAudio_PaDeviceInfo_1getNameBytes (JNIEnv *, jclass, jlong); +/* + * Class: net_java_sip_communicator_impl_neomedia_portaudio_PortAudio + * Method: PaDeviceInfo_getTransportTypeBytes + * Signature: (J)[B + */ +JNIEXPORT jbyteArray JNICALL Java_net_java_sip_communicator_impl_neomedia_portaudio_PortAudio_PaDeviceInfo_1getTransportTypeBytes + (JNIEnv *, jclass, jlong); + +/* + * Class: net_java_sip_communicator_impl_neomedia_portaudio_PortAudio + * Method: PaDeviceInfo_getDeviceUIDBytes + * Signature: (J)[B + */ +JNIEXPORT jbyteArray JNICALL Java_net_java_sip_communicator_impl_neomedia_portaudio_PortAudio_PaDeviceInfo_1getDeviceUIDBytes + (JNIEnv *, jclass, jlong); + /* * Class: org_jitsi_impl_neomedia_portaudio_PortAudio * Method: PaHostApiInfo_getDefaultInputDevice diff --git a/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudio.java b/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudio.java index e9a08476fa023f1b2605b4307ab99bb9f54641cb..2f3212fc4fe37ca5c855e86068067504bddd4ced 100644 --- a/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudio.java +++ b/src/net/java/sip/communicator/impl/neomedia/portaudio/PortAudio.java @@ -615,6 +615,73 @@ public static native double PaDeviceInfo_getDefaultSampleRate( */ private static native byte[] PaDeviceInfo_getNameBytes(long deviceInfo); + /** + * Tranpsort type for the device: BuiltIn, USB, BLuetooth, etc. + * @param deviceInfo device info pointer. + * @return The transport type identifier. + */ + public static native byte[] PaDeviceInfo_getTransportTypeBytes( + long deviceInfo); + + /** + * Tranpsort type for the device: BuiltIn, USB, BLuetooth, etc. + * @param deviceInfo device info pointer. + * @return The transport type identifier. + */ + public static String PaDeviceInfo_getTransportType(long deviceInfo) + { + byte[] typeBytes = PaDeviceInfo_getTransportTypeBytes(deviceInfo); + if(typeBytes == null) + { + return null; + } + + Charset defaultCharset = Charset.defaultCharset(); + String charsetName + = (defaultCharset == null) ? "UTF-8" : defaultCharset.name(); + try + { + return new String(typeBytes, charsetName); + } + catch (UnsupportedEncodingException ueex) + { + return new String(typeBytes); + } + } + + /** + * Device UID for the device (persistent across boots). + * @param deviceInfo device info pointer. + * @return The device UID. + */ + public static native byte[] PaDeviceInfo_getDeviceUIDBytes(long deviceInfo); + + /** + * Device UID for the device (persistent across boots). + * @param deviceInfo device info pointer. + * @return The device UID. + */ + public static String PaDeviceInfo_getDeviceUID(long deviceInfo) + { + byte[] uidBytes = PaDeviceInfo_getDeviceUIDBytes(deviceInfo); + if(uidBytes == null) + { + return null; + } + + Charset defaultCharset = Charset.defaultCharset(); + String charsetName + = (defaultCharset == null) ? "UTF-8" : defaultCharset.name(); + try + { + return new String(uidBytes, charsetName); + } + catch (UnsupportedEncodingException ueex) + { + return new String(uidBytes); + } + } + /** * The default input device for this host API. * @param hostApiInfo pointer to host api info structure. diff --git a/src/org/jitsi/impl/neomedia/MediaServiceImpl.java b/src/org/jitsi/impl/neomedia/MediaServiceImpl.java index bfd1ac9312d00e0d2253b2bae94c531186649823..6a173915ee54fc7075e9324d63de7f366ac6e253 100644 --- a/src/org/jitsi/impl/neomedia/MediaServiceImpl.java +++ b/src/org/jitsi/impl/neomedia/MediaServiceImpl.java @@ -508,7 +508,7 @@ public List<MediaDevice> getDevices( MediaType mediaType, MediaUseCase useCase) { - List<CaptureDeviceInfo> cdis; + List<? extends CaptureDeviceInfo> cdis; List<MediaDeviceImpl> privateDevices; if (MediaType.VIDEO.equals(mediaType)) @@ -528,8 +528,7 @@ public List<MediaDevice> getDevices( privateDevices = audioDevices; break; case VIDEO: - cdis - = getDeviceConfiguration().getAvailableVideoCaptureDevices( + cdis = getDeviceConfiguration().getAvailableVideoCaptureDevices( useCase); privateDevices = videoDevices; break; @@ -555,7 +554,8 @@ public List<MediaDevice> getDevices( while (deviceIter.hasNext()) { - Iterator<CaptureDeviceInfo> cdiIter = cdis.iterator(); + Iterator<? extends CaptureDeviceInfo> cdiIter + = cdis.iterator(); CaptureDeviceInfo captureDeviceInfo = deviceIter.next().getCaptureDeviceInfo(); boolean deviceIsFound = false; diff --git a/src/org/jitsi/impl/neomedia/device/AudioSystem.java b/src/org/jitsi/impl/neomedia/device/AudioSystem.java index 70d1bfd5f34b9509055500c0f326c58d56b6953d..b828ab6ec0e8e0da75869af9008dfa6efea83a73 100644 --- a/src/org/jitsi/impl/neomedia/device/AudioSystem.java +++ b/src/org/jitsi/impl/neomedia/device/AudioSystem.java @@ -112,9 +112,9 @@ protected AudioSystem(String locatorProtocol, int features) * * @return The list of a kind of devices: cpature, notify or playback. */ - public List<CaptureDeviceInfo> getDevices(int index) + public List<ExtendedCaptureDeviceInfo> getDevices(int index) { - return this.devices[index].getDevices(getLocatorProtocol()); + return this.devices[index].getDevices(); } /** @@ -127,9 +127,11 @@ public List<CaptureDeviceInfo> getDevices(int index) * @return The selected device for a specific kind: cpature, notify or * playback. */ - public CaptureDeviceInfo getDevice(int index) + public ExtendedCaptureDeviceInfo getDevice(int index) { - return this.devices[index].getDevice(getLocatorProtocol()); + return this.devices[index].getDevice( + getLocatorProtocol(), + getDevices(index)); } /** @@ -139,7 +141,7 @@ public CaptureDeviceInfo getDevice(int index) * notify or playback. */ protected void setCaptureDevices( - List<CaptureDeviceInfo> activeCaptureDevices) + List<ExtendedCaptureDeviceInfo> activeCaptureDevices) { this.devices[CAPTURE_INDEX].setActiveDevices(activeCaptureDevices); } @@ -153,9 +155,16 @@ protected void setCaptureDevices( * @param save Flag set to true in order to save this choice in the * configuration. False otherwise. */ - public void setDevice(int index, CaptureDeviceInfo device, boolean save) + public void setDevice( + int index, + ExtendedCaptureDeviceInfo device, + boolean save) { - this.devices[index].setDevice(getLocatorProtocol(), device, save); + this.devices[index].setDevice( + getLocatorProtocol(), + device, + save, + getDevices(index)); } /** @@ -164,7 +173,7 @@ public void setDevice(int index, CaptureDeviceInfo device, boolean save) * @param activePlaybackDevices The list of the active devices. */ protected void setPlaybackDevices( - List<CaptureDeviceInfo> activePlaybackDevices) + List<ExtendedCaptureDeviceInfo> activePlaybackDevices) { this.devices[PLAYBACK_INDEX].setActiveDevices(activePlaybackDevices); // The active notify device list is a copy of the playback one. @@ -225,34 +234,23 @@ protected void postInitialize() */ protected void postInitializeSpecificDevices(int index) { - // If there is a selected device, checks if it is part of the current - // active devices. - if (this.devices[index].getDevice(getLocatorProtocol()) != null) - { - List<CaptureDeviceInfo> devices = this.devices[index].getDevices( - getLocatorProtocol()); - - if ((devices == null) - || !devices.contains(this.devices[index].getDevice( - getLocatorProtocol()))) - { - // The selected device is not part of the active devices, then - // set it to null (but not saved). - this.devices[index].setDevice( - getLocatorProtocol(), - null, - false); - } - } - else - { - /* - * If the device is null, it means that a device is to be - * used as the default. The default in question may have - * changed. - */ - this.devices[index].setDevice(getLocatorProtocol(), null, false); - } + // Gets all current active devies. + List<ExtendedCaptureDeviceInfo> activeDevices = this.getDevices(index); + // Gets the default device. + ExtendedCaptureDeviceInfo selectedActiveDevice + = this.devices[index].getDevice( + getLocatorProtocol(), + activeDevices); + // Sets the default device as selected (this function will only fire a + // property change if the device has changed from previous + // configuration). + // This "set" part is important because only the fire property event + // provides a way to get hot plugged devices working during a call. + this.devices[index].setDevice( + getLocatorProtocol(), + selectedActiveDevice, + false, + activeDevices); } /** diff --git a/src/org/jitsi/impl/neomedia/device/CaptureDevices.java b/src/org/jitsi/impl/neomedia/device/CaptureDevices.java index 05dee0e657720655793690b1bbc8836997316eee..3638784c76da9c95306599d29c6eb8e31320aad4 100644 --- a/src/org/jitsi/impl/neomedia/device/CaptureDevices.java +++ b/src/org/jitsi/impl/neomedia/device/CaptureDevices.java @@ -25,14 +25,14 @@ public class CaptureDevices extends Devices { /** - * The flag nuber if the capture device is null. + * The property of the capture devices. */ - protected static final int FLAG_DEVICE_IS_NULL = 1; + public static final String PROP_DEVICE = "captureDevice"; /** - * The property of the capture devices. + * The list of active (actually plugged-in) capture devices. */ - public static final String PROP_DEVICE = "captureDevice"; + private List<ExtendedCaptureDeviceInfo> activeCaptureDevices = null; /** * Initializes the capture device list managment. @@ -47,43 +47,34 @@ public CaptureDevices(AudioSystem audioSystem) /** * Returns the list of the active devices. * - * @param locator The string representation of the locator. - * * @return The list of the active devices. */ - public List<CaptureDeviceInfo> getDevices(String locator) + public List<ExtendedCaptureDeviceInfo> getDevices() { - MediaServiceImpl mediaServiceImpl - = NeomediaServiceUtils.getMediaServiceImpl(); - DeviceConfiguration deviceConfiguration = (mediaServiceImpl == null) - ? null - : mediaServiceImpl.getDeviceConfiguration(); - List<CaptureDeviceInfo> deviceList; + Format[] formats; + Format format = new AudioFormat(AudioFormat.LINEAR, -1, 16, -1); + List<ExtendedCaptureDeviceInfo> devices = null; - if (deviceConfiguration == null) + if(this.activeCaptureDevices != null) { - /* - * XXX The initialization of MediaServiceImpl is very complex so it - * is wise to not reference it at the early stage of its - * initialization. The same goes for DeviceConfiguration. If for - * some reason one of the two is not available at this time, just - * fall back go something that makes sense. - */ - @SuppressWarnings("unchecked") - Vector<CaptureDeviceInfo> audioCaptureDeviceInfos - = CaptureDeviceManager.getDeviceList( - new AudioFormat(AudioFormat.LINEAR, -1, 16, -1)); + devices = new ArrayList<ExtendedCaptureDeviceInfo>( + this.activeCaptureDevices.size()); - deviceList = audioCaptureDeviceInfos; - } - else - { - deviceList = deviceConfiguration.getAvailableAudioCaptureDevices(); + for(ExtendedCaptureDeviceInfo device: this.activeCaptureDevices) + { + formats = device.getFormats(); + for(int i = 0; i < formats.length; ++i) + { + if(formats[i].matches(format)) + { + devices.add(device); + i = formats.length; + } + } + } } - return DeviceSystem.filterDeviceListByLocatorProtocol( - deviceList, - locator); + return devices; } /** @@ -91,7 +82,7 @@ public List<CaptureDeviceInfo> getDevices(String locator) * * @param activeDevices The list of the active devices. */ - public void setActiveDevices(List<CaptureDeviceInfo> activeDevices) + public void setActiveDevices(List<ExtendedCaptureDeviceInfo> activeDevices) { if(activeDevices != null) { @@ -114,16 +105,10 @@ public void setActiveDevices(List<CaptureDeviceInfo> activeDevices) } } } - } - /** - * Returns the flag nuber if the capture device is null. - * - * @return The flag nuber if the capture device is null. - */ - protected int getFlagDeviceIsNull() - { - return FLAG_DEVICE_IS_NULL; + this.activeCaptureDevices = (activeDevices == null) + ? null + : new ArrayList<ExtendedCaptureDeviceInfo>(activeDevices); } /** diff --git a/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java b/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java index 1c8ba4d31a1850eaf5b105dc54addc8205dfae32..5affd454f3938ee20ab83ac6f235344e37acaf24 100644 --- a/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java +++ b/src/org/jitsi/impl/neomedia/device/DeviceConfiguration.java @@ -395,7 +395,7 @@ private CaptureDeviceInfo extractConfiguredVideoCaptureDevice(Format format) * @return the CaptureDeviceInfo of a device that we could use for audio * capture. */ - public CaptureDeviceInfo getAudioCaptureDevice() + public ExtendedCaptureDeviceInfo getAudioCaptureDevice() { AudioSystem audioSystem = getAudioSystem(); @@ -414,14 +414,9 @@ public CaptureDeviceInfo getAudioCaptureDevice() * capture devices available through this * <tt>DeviceConfiguration</tt> */ - public List<CaptureDeviceInfo> getAvailableAudioCaptureDevices() + public List<ExtendedCaptureDeviceInfo> getAvailableAudioCaptureDevices() { - @SuppressWarnings("unchecked") - Vector<CaptureDeviceInfo> audioCaptureDevices - = CaptureDeviceManager.getDeviceList( - new AudioFormat(AudioFormat.LINEAR, -1, 16, -1)); - - return audioCaptureDevices; + return audioSystem.getDevices(AudioSystem.CAPTURE_INDEX); } public AudioSystem getAudioSystem() @@ -445,7 +440,7 @@ public AudioSystem[] getAvailableAudioSystems() if (!NoneAudioSystem.LOCATOR_PROTOCOL.equalsIgnoreCase( audioSystem.getLocatorProtocol())) { - List<CaptureDeviceInfo> captureDevices + List<ExtendedCaptureDeviceInfo> captureDevices = audioSystem.getDevices(AudioSystem.CAPTURE_INDEX); if ((captureDevices == null) @@ -459,14 +454,14 @@ public AudioSystem[] getAvailableAudioSystems() } else { - List<CaptureDeviceInfo> notifyDevices + List<ExtendedCaptureDeviceInfo> notifyDevices = audioSystem.getDevices( AudioSystem.NOTIFY_INDEX); if ((notifyDevices == null) || (notifyDevices.size() <= 0)) { - List<CaptureDeviceInfo> playbackDevices + List<ExtendedCaptureDeviceInfo> playbackDevices = audioSystem.getDevices( AudioSystem.PLAYBACK_INDEX); diff --git a/src/org/jitsi/impl/neomedia/device/Devices.java b/src/org/jitsi/impl/neomedia/device/Devices.java index bc34943b2f092a924220ee84c8cd0979d27a791c..a92411eeba6fd84b5811f2c966d2589b15d435e7 100644 --- a/src/org/jitsi/impl/neomedia/device/Devices.java +++ b/src/org/jitsi/impl/neomedia/device/Devices.java @@ -25,19 +25,14 @@ public abstract class Devices /** * The selected active device. */ - protected CaptureDeviceInfo device = null; + protected ExtendedCaptureDeviceInfo device = null; /** - * The list of device names saved by the congifuration service and + * The list of device ID/names saved by the congifuration service and * previously saved given user preference order. */ protected List<String> devicePreferences = new ArrayList<String>(); - /** - * The flags that can save if the FLAG_DEVICE_IS_NULL state is set. - */ - private int flags; - /** * The audio system managing this device list. */ @@ -57,103 +52,74 @@ public Devices(AudioSystem audioSystem) * Gets the selected active device. * * @param locator The string representation of the locator. + * @param activeDevices The list of the active devices. * * @return The selected active device. */ - public CaptureDeviceInfo getDevice(String locator) + public ExtendedCaptureDeviceInfo getDevice( + String locator, + List<ExtendedCaptureDeviceInfo> activeDevices) { - List<CaptureDeviceInfo> devices = getDevices(locator); - - // Reinit the selected device if this one is no more in the active list. - if (this.device != null) + if (activeDevices != null) { - if ((devices == null) || !devices.contains(this.device)) + String property = getPropDevice(); + loadDevicePreferences(locator, property); + renameOldFashionedIdentifier(activeDevices); + + // Search if an active device is a new one (is not stored in the + // preferences yet). If true, then active this device and set it as + // default device (only for USB devices since the user has + // deliberately plugged-in the device). + for(ExtendedCaptureDeviceInfo activeDevice : activeDevices) { - setDevice(locator, null, false); + if(!devicePreferences.contains(activeDevice.getIdentifier())) + { + // Adds the device in the preference list (to the end of the + // list, but the save device will push it to the top of + // active devices). + this.saveDevice( + locator, + property, + activeDevice, + activeDevices, + activeDevice.isSameTransportType("USB")); + } } - } - - CaptureDeviceInfo device = this.device; - // If the device is null and the device is not desactivated, then try to - // find the user preferred one between the active devices. - if ((device == null) && ((flags & getFlagDeviceIsNull()) == 0)) - { - if ((devices != null) && (devices.size() > 0)) + // Search if an active device match one of the previsouly configured + // in the preferences. + for(int i = 0; i < devicePreferences.size(); ++i) { - device = loadDevice(locator, getPropDevice(), devices); - if (device == null) - device = devices.get(0); + for(ExtendedCaptureDeviceInfo activeDevice : activeDevices) + { + // If we have found the "preferred" device among active + // device. + if(devicePreferences.get(i).equals( + activeDevice.getIdentifier())) + { + return activeDevice; + } + // If the "none" device is the "preferred" device among + // "active" device. + else if(devicePreferences.get(i).equals( + NoneAudioSystem.LOCATOR_PROTOCOL)) + { + return null; + } + } } } - return device; + + // Else if nothing was found, then returns null. + return null; } /** * Returns the list of the active devices. * - * @param locator The string representation of the locator. - * * @return The list of the active devices. */ - public abstract List<CaptureDeviceInfo> getDevices(String locator); - - /** - * Loads the user's preference with respect to a <tt>CaptureDeviceInfo</tt> - * among a specific list of <tt>CaptureDeviceInfo</tt>s from the - * <tt>ConfigurationService</tt>. - * - * @param locator The string representation of the locator. - * @param property the name of the <tt>ConfigurationService</tt> property - * which specifies the user's preference with respect to a - * <tt>CaptureDeviceInfo</tt> among the specified list of - * <tt>CaptureDeviceInfo</tt>s - * @param devices the list of <tt>CaptureDeviceInfo</tt>s which are valid - * selections for the user's preference - * @return a <tt>CaptureDeviceInfo</tt> among the specified <tt>devices</tt> - * which represents the user's preference stored in the - * <tt>ConfigurationService</tt> - */ - private CaptureDeviceInfo loadDevice( - String locator, - String property, - List<CaptureDeviceInfo> devices) - { - loadDevicePreferences(locator, property); - - // Search if an active device is a new one (is not stored in the - // preferences yet). If true, then active this device and set it as - // default device. - for(CaptureDeviceInfo device : devices) - { - if(!devicePreferences.contains(device.getName())) - { - // Adds the device in the preference list (to the end of the - // list, but the save device will push it to the top of active - // devices). - devicePreferences.add(device.getName()); - this.saveDevice(locator, property, device, false); - } - } - // Search if an active device match one of the previsouly configured in - // the preferences. - for(int i = 0; i < devicePreferences.size(); ++i) - { - for(CaptureDeviceInfo device : devices) - if (devicePreferences.get(i).equals(device.getName())) - return device; - } - - // If no active devices matches a configured one, then gets the first - // active device available. - if(devices.size() > 0) - { - return devices.get(0); - } - - // Else if nothing was found, then returns null. - return null; - } + public abstract List<ExtendedCaptureDeviceInfo> getDevices(); /** * Loads device name ordered with user's preference from the @@ -177,20 +143,18 @@ private void loadDevicePreferences(String locator, String property) + property + "_list"; - String deviceNamesString = cfg.getString(new_property); + String deviceIdentifiersString = cfg.getString(new_property); - if (deviceNamesString != null - && !NoneAudioSystem.LOCATOR_PROTOCOL.equalsIgnoreCase( - deviceNamesString)) + if (deviceIdentifiersString != null) { devicePreferences.clear(); // We must parce the string in order to load the device list. - String[] deviceNames = deviceNamesString - .substring(2, deviceNamesString.length() - 2) + String[] deviceIdentifiers = deviceIdentifiersString + .substring(2, deviceIdentifiersString.length() - 2) .split("\", \""); - for(int i = 0; i < deviceNames.length; ++i) + for(int i = 0; i < deviceIdentifiers.length; ++i) { - devicePreferences.add(deviceNames[i]); + devicePreferences.add(deviceIdentifiers[i]); } } // Else, use the old property to load the last preferred device. @@ -204,14 +168,14 @@ private void loadDevicePreferences(String locator, String property) + "." + property; - deviceNamesString = cfg.getString(old_property); + deviceIdentifiersString = cfg.getString(old_property); - if (deviceNamesString != null + if (deviceIdentifiersString != null && !NoneAudioSystem.LOCATOR_PROTOCOL.equalsIgnoreCase( - deviceNamesString)) + deviceIdentifiersString)) { devicePreferences.clear(); - devicePreferences.add(deviceNamesString); + devicePreferences.add(deviceIdentifiersString); } } } @@ -224,15 +188,16 @@ private void loadDevicePreferences(String locator, String property) * @param property the name of the <tt>ConfigurationService</tt> property * into which the user's preference with respect to the specified * <tt>CaptureDeviceInfo</tt> is to be saved - * @param device the <tt>CaptureDeviceInfo</tt> selected by the user. - * @param isNull <tt>true</tt> if the user's preference with respect to the - * specified <tt>device</tt> is <tt>null</tt>; otherwise, <tt>false</tt> + * @param selectedDevice The device selected by the user. + * @param activeDevices The list of the active devices. + * @param isSelected True if the device is the selected one. */ private void saveDevice( String locator, String property, - CaptureDeviceInfo device, - boolean isNull) + ExtendedCaptureDeviceInfo device, + List<ExtendedCaptureDeviceInfo> activeDevices, + boolean isSelected) { ConfigurationService cfg = LibJitsi.getConfigurationService(); @@ -243,62 +208,41 @@ private void saveDevice( + "." + locator + "." + property + "_list"; - if(device == null) + + String selectedDeviceIdentifier = NoneAudioSystem.LOCATOR_PROTOCOL; + if(device != null) { - if(isNull) - { - cfg.setProperty(property, NoneAudioSystem.LOCATOR_PROTOCOL); - } - else - { - cfg.removeProperty(property); - } + selectedDeviceIdentifier = device.getIdentifier(); + } + + // Sorts the user preferences to put the selected device on top. + devicePreferences.remove(selectedDeviceIdentifier); + if(isSelected) + { + int firstActiveIndex = getFirstActiveIndexFromDevicePreferences( + locator, + activeDevices); + devicePreferences.add( + firstActiveIndex, + selectedDeviceIdentifier); } else { - // Sorts the user preferences to put the selected device on top. - ArrayList resultList - = new ArrayList<String>(devicePreferences.size() + 1); - List<CaptureDeviceInfo> devices = getDevices(locator); - boolean firstActiveFound = false; - for(int i = 0; i < devicePreferences.size(); ++i) - { - // Checks if this element is an active device. - for(int j = 0; !firstActiveFound && j < devices.size(); ++j) - { - if(devicePreferences.get(i).equals( - devices.get(j).getName())) - { - // The first active device is found, then place the - // selected device at the previous place. - resultList.add(device.getName()); - firstActiveFound = true; - } - } - - // Checks that we do not add dupplicate of the selected - // device> - if(!devicePreferences.get(i).equals(device.getName())) - { - resultList.add(devicePreferences.get(i)); - } - } - // Updates the preferences list with the ew one computed. - devicePreferences = resultList; + devicePreferences.add(selectedDeviceIdentifier); + } - // Saves the user preferences. - StringBuffer value = new StringBuffer("[\""); - if(devicePreferences.size() > 0) + // Saves the user preferences. + StringBuffer value = new StringBuffer("[\""); + if(devicePreferences.size() > 0) + { + value.append(devicePreferences.get(0)); + for(int i = 1; i < devicePreferences.size(); ++i) { - value.append(devicePreferences.get(0)); - for(int i = 1; i < devicePreferences.size(); ++i) - { - value.append("\", \"" + devicePreferences.get(i)); - } + value.append("\", \"" + devicePreferences.get(i)); } - value.append("\"]"); - cfg.setProperty(property, value.toString()); } + value.append("\"]"); + cfg.setProperty(property, value.toString()); } } @@ -309,41 +253,33 @@ private void saveDevice( * @param device The selected active device. * @param save Flag set to true in order to save this choice in the * configuration. False otherwise. + * @param activeDevices The list of the active devices. */ public void setDevice( String locator, - CaptureDeviceInfo device, - boolean save) + ExtendedCaptureDeviceInfo device, + boolean save, + List<ExtendedCaptureDeviceInfo> activeDevices) { // Checks if there is a change. - if ((this.device != device) || (device == null)) + if ((device == null) || !device.equals(this.device)) { - CaptureDeviceInfo oldValue = this.device; - this.device = device; + ExtendedCaptureDeviceInfo oldValue = this.device; // Saves the new selected device in top of the user preferences. if (save) { - boolean isNull = (this.device == null); - - if (isNull) - flags |= getFlagDeviceIsNull(); - else - flags &= ~getFlagDeviceIsNull(); - - saveDevice(locator, getPropDevice(), this.device, isNull); + saveDevice( + locator, + getPropDevice(), + device, + activeDevices, + true); } + this.device = device; - CaptureDeviceInfo newValue = getDevice(locator); - - if (oldValue != newValue) - { - if(this.audioSystem != null) - { - this.audioSystem - .propertyChange(getPropDevice(), oldValue, newValue); - } - } + this.audioSystem + .propertyChange(getPropDevice(), oldValue, this.device); } } @@ -353,19 +289,101 @@ public void setDevice( * @param activeDevices The list of the active devices. */ public abstract void setActiveDevices( - List<CaptureDeviceInfo> activeDevices); + List<ExtendedCaptureDeviceInfo> activeDevices); /** - * Returns the flag nuber if the capture device is null. + * Returns the property of the capture devices. * - * @return The flag nuber if the capture device is null. + * @return The property of the capture devices. */ - protected abstract int getFlagDeviceIsNull(); + protected abstract String getPropDevice(); /** - * Returns the property of the capture devices. + * Returns the index of the first active device from the device preference + * list. * - * @return The property of the capture devices. + * @param locator The string representation of the locator. + * @param activeDevices The list of the active devices. + * + * @return The index of the first active device from the device preference + * list. Or the size of the device preference list if all devices are + * inactive. */ - protected abstract String getPropDevice(); + private int getFirstActiveIndexFromDevicePreferences( + String locator, + List<ExtendedCaptureDeviceInfo> activeDevices) + { + int i; + int j; + // Searches for the first active device. + for(i = 0; i < devicePreferences.size(); ++i) + { + // Checks if this element is an active device. + for(j = 0; j < activeDevices.size(); ++j) + { + if(devicePreferences.get(i).equals( + activeDevices.get(j).getIdentifier()) + || devicePreferences.get(i).equals( + NoneAudioSystem.LOCATOR_PROTOCOL)) + { + // The first active device is found. + return i; + } + } + } + // There is no active devices, then returns the size of the device + // peference list. + return devicePreferences.size(); + } + + /** + * Renames the old fashioned identifier (name only), into new fashioned one + * (UID, or name + transport type). + * + * @param activeDevices The list of the active devices. + */ + public void renameOldFashionedIdentifier( + List<ExtendedCaptureDeviceInfo> activeDevices) + { + String name; + String id; + int nameIndex; + int idIndex; + // Renames the old fashioned device identifier for all active devices. + for(int i = 0; i < activeDevices.size(); ++i) + { + name = activeDevices.get(i).getName(); + id = activeDevices.get(i).getIdentifier(); + // We can only switch to the new fashioned notation, only if the OS + // api give us a unique identifier (different from the device name). + if(!name.equals(id)) + { + do + { + nameIndex = devicePreferences.indexOf( + activeDevices.get(i).getName()); + idIndex = devicePreferences.indexOf( + activeDevices.get(i).getIdentifier()); + // If there is one old fashioned identifier. + if(nameIndex != -1) + { + // If the correspondant new fashioned identifier does + // not exists, then renames the old one into the new + // one. + if(idIndex == -1) + { + devicePreferences.set(nameIndex, + activeDevices.get(i).getIdentifier()); + } + // Else removes the dupplicate. + else + { + devicePreferences.remove(nameIndex); + } + } + } + while(nameIndex != -1); + } + } + } } diff --git a/src/org/jitsi/impl/neomedia/device/ExtendedCaptureDeviceInfo.java b/src/org/jitsi/impl/neomedia/device/ExtendedCaptureDeviceInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..87ca6059264fdf53142f43d8a8dbd9132daa3e95 --- /dev/null +++ b/src/org/jitsi/impl/neomedia/device/ExtendedCaptureDeviceInfo.java @@ -0,0 +1,147 @@ +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package org.jitsi.impl.neomedia.device; + +import java.util.*; + +import javax.media.*; + +/** + * Adds some important information (i.e. device type, UID.) to FMJ + * CaptureDeviceInfo. + * + * @author Vincent Lucas + */ +public class ExtendedCaptureDeviceInfo + extends CaptureDeviceInfo +{ + /** + * The device UID (unique identifier). + */ + private String UID = null; + + /** + * The device transport type. + */ + private String transportType = null; + + /** + * Constructs a CaptureDeviceInfo object with the specified name, media + * locator, and array of Format objects. + * + * @param captureDeiceInfo the device info. + * @param uid The device UID (unique identifier). + * @param transportType The device transport type. + */ + public ExtendedCaptureDeviceInfo( + CaptureDeviceInfo captureDeviceInfo, + String UID, + String transportType) + { + this( + captureDeviceInfo.getName(), + captureDeviceInfo.getLocator(), + captureDeviceInfo.getFormats(), + UID, + transportType); + } + + /** + * Constructs a CaptureDeviceInfo object with the specified name, media + * locator, and array of Format objects. + * + * @param name A String that contains the name of the device. + * @param locator The MediaLocator that uniquely specifies the device. + * @param formats An array of the output formats supported by the device. + * @param uid The device UID (unique identifier). + * @param transportType The device transport type. + */ + public ExtendedCaptureDeviceInfo( + String name, + MediaLocator locator, + Format[] formats, + String UID, + String transportType) + { + super(name, locator, formats); + + this.UID = UID; + this.transportType = transportType; + } + + /** + * Returns the device UID (unique identifier). + * + * @return The device UID (unique identifier). + */ + public String getUID() + { + return this.UID; + } + + /** + * Returns the device transport type. + * + * @return The device transport type. + */ + public String getTransportType() + { + return this.transportType; + } + + /** + * Returns if the transport type matches the one given in parameter. + * + * The transport type to compare with. + * + * @return True if the transport type matches the one given in parameter. + * False otherwise. + */ + public boolean isSameTransportType(String transportType) + { + if(this.transportType == null) + { + return (transportType == null); + } + return this.transportType.equals(transportType); + } + + @Override + public boolean equals(Object obj) + { + if(obj != null + && obj instanceof ExtendedCaptureDeviceInfo) + { + return this.getIdentifier().equals( + ((ExtendedCaptureDeviceInfo) obj).getIdentifier()); + } + return false; + } + + @Override + public int hashCode() + { + return this.getIdentifier().hashCode(); + } + + /** + * Returns the device identifier used to save and load device preferences. + * It is composed by the system UID if not null. Otherwise returns the + * device name and (if not null) the transport type. + * + * @return The device identifer. + */ + public String getIdentifier() + { + String id = this.UID; + if(this.UID == null) + { + id = this.name; + } + return id; + } +} diff --git a/src/org/jitsi/impl/neomedia/device/NotifyDevices.java b/src/org/jitsi/impl/neomedia/device/NotifyDevices.java index ff76b22acc25ef5c704b25f567de056ad56c1347..43512c97b2cde3e03aba34ce3eb02481591d1d2c 100644 --- a/src/org/jitsi/impl/neomedia/device/NotifyDevices.java +++ b/src/org/jitsi/impl/neomedia/device/NotifyDevices.java @@ -20,11 +20,6 @@ public class NotifyDevices extends PlaybackDevices { - /** - * The flag nuber if the notify device is null. - */ - protected static final int FLAG_DEVICE_IS_NULL = 2; - /** * The property of the notify devices. */ @@ -40,16 +35,6 @@ public NotifyDevices(AudioSystem audioSystem) super(audioSystem); } - /** - * Returns the flag nuber if the capture device is null. - * - * @return The flag nuber if the capture device is null. - */ - protected int getFlagDeviceIsNull() - { - return FLAG_DEVICE_IS_NULL; - } - /** * Returns the property of the capture devices. * diff --git a/src/org/jitsi/impl/neomedia/device/PlaybackDevices.java b/src/org/jitsi/impl/neomedia/device/PlaybackDevices.java index c2ba74231c934b636f628c48d2de43a2bc4abb83..05d892ce42796ce491e97effdaee479402cfb4cc 100644 --- a/src/org/jitsi/impl/neomedia/device/PlaybackDevices.java +++ b/src/org/jitsi/impl/neomedia/device/PlaybackDevices.java @@ -20,11 +20,6 @@ public class PlaybackDevices extends Devices { - /** - * The flag nuber if the playback device is null. - */ - protected static final int FLAG_DEVICE_IS_NULL = 4; - /** * The property of the playback devices. */ @@ -33,7 +28,7 @@ public class PlaybackDevices /** * The list of active (actually plugged-in) playback devices. */ - private List<CaptureDeviceInfo> activePlaybackDevices = null; + private List<ExtendedCaptureDeviceInfo> activePlaybackDevices = null; /** * Initializes the playback device list managment. @@ -48,18 +43,14 @@ public PlaybackDevices(AudioSystem audioSystem) /** * Returns the list of the active devices. * - * @param locator The string representation of the locator. - * * @return The list of the active devices. */ - public List<CaptureDeviceInfo> getDevices(String locator) + public List<ExtendedCaptureDeviceInfo> getDevices() { - List<CaptureDeviceInfo> activePlaybackDevices - = this.activePlaybackDevices; - - return (activePlaybackDevices == null) + return (this.activePlaybackDevices == null) ? null - : new ArrayList<CaptureDeviceInfo>(activePlaybackDevices); + : new ArrayList<ExtendedCaptureDeviceInfo>( + this.activePlaybackDevices); } /** @@ -67,21 +58,11 @@ public List<CaptureDeviceInfo> getDevices(String locator) * * @param activeDevices The list of the active devices. */ - public void setActiveDevices(List<CaptureDeviceInfo> activeDevices) + public void setActiveDevices(List<ExtendedCaptureDeviceInfo> activeDevices) { this.activePlaybackDevices = (activeDevices == null) ? null - : new ArrayList<CaptureDeviceInfo>(activeDevices); - } - - /** - * Returns the flag nuber if the capture device is null. - * - * @return The flag nuber if the capture device is null. - */ - protected int getFlagDeviceIsNull() - { - return FLAG_DEVICE_IS_NULL; + : new ArrayList<ExtendedCaptureDeviceInfo>(activeDevices); } /** diff --git a/src/org/jitsi/impl/neomedia/device/PortAudioSystem.java b/src/org/jitsi/impl/neomedia/device/PortAudioSystem.java index 09b8c170282510eff7a205facb740b04cd3028b3..32a142000d74fd9a1a7bcebfc094b726afe0ea85 100644 --- a/src/org/jitsi/impl/neomedia/device/PortAudioSystem.java +++ b/src/org/jitsi/impl/neomedia/device/PortAudioSystem.java @@ -100,10 +100,10 @@ protected void doInitialize() long sampleFormat = PortAudio.getPaSampleFormat(sampleSizeInBits); int defaultInputDeviceIndex = PortAudio.Pa_GetDefaultInputDevice(); int defaultOutputDeviceIndex = PortAudio.Pa_GetDefaultOutputDevice(); - List<CaptureDeviceInfo> captureDevices - = new LinkedList<CaptureDeviceInfo>(); - List<CaptureDeviceInfo> playbackDevices - = new LinkedList<CaptureDeviceInfo>(); + List<ExtendedCaptureDeviceInfo> captureDevices + = new LinkedList<ExtendedCaptureDeviceInfo>(); + List<ExtendedCaptureDeviceInfo> playbackDevices + = new LinkedList<ExtendedCaptureDeviceInfo>(); for (int deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) { @@ -117,30 +117,52 @@ protected void doInitialize() = PortAudio.PaDeviceInfo_getMaxInputChannels(deviceInfo); int maxOutputChannels = PortAudio.PaDeviceInfo_getMaxOutputChannels(deviceInfo); + String transportType + = PortAudio.PaDeviceInfo_getTransportType(deviceInfo); + String deviceUID + = PortAudio.PaDeviceInfo_getDeviceUID(deviceInfo); - CaptureDeviceInfo cdi - = new CaptureDeviceInfo( - name, - new MediaLocator(LOCATOR_PROTOCOL + ":#" + deviceIndex), - new Format[] - { - new AudioFormat( - AudioFormat.LINEAR, - (maxInputChannels > 0) - ? getSupportedSampleRate( - true, - deviceIndex, - channels, - sampleFormat) - : PortAudio.DEFAULT_SAMPLE_RATE, - sampleSizeInBits, - channels, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED /* frameSizeInBits */, - Format.NOT_SPECIFIED /* frameRate */, - Format.byteArray) - }); + ExtendedCaptureDeviceInfo cdi = null; + List<ExtendedCaptureDeviceInfo> devices = getDevices(CAPTURE_INDEX); + boolean found = false; + // Search if the device is already initiated. If yes used it, + // otherwise a call currently using this device will fail. + for(int i = 0; devices !=null && i < devices.size() && !found; ++i) + { + if(devices.get(i).getUID().equals(deviceUID)) + { + cdi = devices.get(i); + found = true; + } + } + // If not found, then we must initialized this new device. + if(!found) + { + cdi = new ExtendedCaptureDeviceInfo( + name, + new MediaLocator(LOCATOR_PROTOCOL + ":#" + deviceIndex), + new Format[] + { + new AudioFormat( + AudioFormat.LINEAR, + (maxInputChannels > 0) + ? getSupportedSampleRate( + true, + deviceIndex, + channels, + sampleFormat) + : PortAudio.DEFAULT_SAMPLE_RATE, + sampleSizeInBits, + channels, + AudioFormat.LITTLE_ENDIAN, + AudioFormat.SIGNED, + Format.NOT_SPECIFIED /* frameSizeInBits */, + Format.NOT_SPECIFIED /* frameRate */, + Format.byteArray) + }, + deviceUID, + transportType); + } if (maxInputChannels > 0) { diff --git a/src/org/jitsi/impl/neomedia/device/PulseAudioSystem.java b/src/org/jitsi/impl/neomedia/device/PulseAudioSystem.java index 3c76ee51f067e0bd7c6250fa48296bf7fdee6f92..c91ba16c5831fd1282350a7e3ef4d02acaa4f77e 100644 --- a/src/org/jitsi/impl/neomedia/device/PulseAudioSystem.java +++ b/src/org/jitsi/impl/neomedia/device/PulseAudioSystem.java @@ -264,8 +264,8 @@ protected synchronized void doInitialize() { long context = getContext(); - final List<CaptureDeviceInfo> captureDevices - = new LinkedList<CaptureDeviceInfo>(); + final List<ExtendedCaptureDeviceInfo> captureDevices + = new LinkedList<ExtendedCaptureDeviceInfo>(); final List<Format> captureDeviceFormats = new LinkedList<Format>(); PA.source_info_cb_t sourceInfoListCallback = new PA.source_info_cb_t() @@ -290,8 +290,8 @@ public void callback(long c, long i, int eol) } }; - final List<CaptureDeviceInfo> playbackDevices - = new LinkedList<CaptureDeviceInfo>(); + final List<ExtendedCaptureDeviceInfo> playbackDevices + = new LinkedList<ExtendedCaptureDeviceInfo>(); final List<Format> playbackDeviceFormats = new LinkedList<Format>(); PA.sink_info_cb_t sinkInfoListCallback = new PA.sink_info_cb_t() @@ -364,19 +364,23 @@ public void callback(long c, long i, int eol) { captureDevices.add( 0, - new CaptureDeviceInfo( + new ExtendedCaptureDeviceInfo( NULL_DEV_CAPTURE_DEVICE_INFO_NAME, new MediaLocator(LOCATOR_PROTOCOL + ":"), captureDeviceFormats.toArray( - new Format[captureDeviceFormats.size()]))); + new Format[captureDeviceFormats.size()]), + null, + null)); } if (!playbackDevices.isEmpty()) { playbackDevices.add( 0, - new CaptureDeviceInfo( + new ExtendedCaptureDeviceInfo( NULL_DEV_CAPTURE_DEVICE_INFO_NAME, new MediaLocator(LOCATOR_PROTOCOL + ":"), + null, + null, null)); } @@ -447,7 +451,7 @@ public void signalMainloop(boolean waitForAccept) private void sinkInfoListCallback( long context, long sinkInfo, - List<CaptureDeviceInfo> deviceList, + List<ExtendedCaptureDeviceInfo> deviceList, List<Format> formatList) { int sampleSpecFormat = PA.sink_info_get_sample_spec_format(sinkInfo); @@ -461,19 +465,21 @@ private void sinkInfoListCallback( if (description == null) description = name; deviceList.add( - new CaptureDeviceInfo( + new ExtendedCaptureDeviceInfo( description, new MediaLocator( LOCATOR_PROTOCOL + ":" + name), + null, + null, null)); } private void sourceInfoListCallback( long context, long sourceInfo, - List<CaptureDeviceInfo> deviceList, + List<ExtendedCaptureDeviceInfo> deviceList, List<Format> formatList) { int monitorOfSink = PA.source_info_get_monitor_of_sink(sourceInfo); @@ -524,14 +530,16 @@ private void sourceInfoListCallback( if (description == null) description = name; deviceList.add( - new CaptureDeviceInfo( + new ExtendedCaptureDeviceInfo( description, new MediaLocator( LOCATOR_PROTOCOL + ":" + name), sourceInfoFormatList.toArray( - new Format[sourceInfoFormatList.size()]))); + new Format[sourceInfoFormatList.size()]), + null, + null)); } }