Skip to content

Commit

Permalink
IP camera device registry doesn't work with discovery service, fixes #93
Browse files Browse the repository at this point in the history
  • Loading branch information
sarxos committed May 6, 2013
1 parent 8c9ac66 commit 9f001b8
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.Iterator;
import java.util.List;

import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamDevice;
import com.github.sarxos.webcam.WebcamException;

Expand All @@ -29,13 +30,21 @@ public class IpCamDeviceRegistry {
* @param ipcam the IP camera to be register
*/
public static IpCamDevice register(IpCamDevice ipcam) {

for (WebcamDevice d : DEVICES) {
String name = ipcam.getName();
if (d.getName().equals(name)) {
throw new WebcamException(String.format("Webcam with name '%s' is already registered", name));
}
}

DEVICES.add(ipcam);

// run discovery service once to trigger new webcam discovery event
// and keep webcams list up-to-date

Webcam.getDiscoveryService().scan();

return ipcam;
}

Expand Down Expand Up @@ -90,7 +99,17 @@ public static boolean isRegistered(URL url) {
* @param ipcam the IP camera to be unregister
*/
public static boolean unregister(IpCamDevice ipcam) {
return DEVICES.remove(ipcam);
boolean removed = DEVICES.remove(ipcam);

// run discovery service once if device has been removed to
// trigger disconnected webcam discovery event and keep webcams
// list up-to-date

if (removed) {
Webcam.getDiscoveryService().scan();
}

return removed;
}

/**
Expand All @@ -104,6 +123,7 @@ public static boolean unregister(String name) {
IpCamDevice d = di.next();
if (d.getName().equals(name)) {
di.remove();
Webcam.getDiscoveryService().scan();
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,125 +135,127 @@ public synchronized List<Webcam> getWebcams(long timeout, TimeUnit tunit) throws
return Collections.unmodifiableList(webcams);
}

@Override
public void run() {
/**
* Scan for newly added or already removed webcams.
*/
public void scan() {

// do not run if driver does not support discovery
WebcamDiscoveryListener[] listeners = Webcam.getDiscoveryListeners();

if (support == null) {
return;
List<WebcamDevice> tmpnew = driver.getDevices();
List<WebcamDevice> tmpold = null;

try {
tmpold = getDevices(getWebcams(Long.MAX_VALUE, TimeUnit.MILLISECONDS));
} catch (TimeoutException e) {
throw new WebcamException(e);
}

running = true;
// convert to linked list due to O(1) on remove operation on
// iterator versus O(n) for the same operation in array list

// wait initial time interval since devices has been initially
// discovered
List<WebcamDevice> oldones = new LinkedList<WebcamDevice>(tmpold);
List<WebcamDevice> newones = new LinkedList<WebcamDevice>(tmpnew);

Object monitor = new Object();
Iterator<WebcamDevice> oi = oldones.iterator();
Iterator<WebcamDevice> ni = null;

do {
WebcamDevice od = null; // old device
WebcamDevice nd = null; // new device

synchronized (monitor) {
try {
monitor.wait(support.getScanInterval());
} catch (InterruptedException e) {
if (LOG.isTraceEnabled()) {
LOG.error("Interrupted", e);
}
break;
} catch (Exception e) {
throw new RuntimeException("Problem waiting on monitor", e);
}
}
// reduce lists

WebcamDiscoveryListener[] listeners = Webcam.getDiscoveryListeners();
while (oi.hasNext()) {

// do nothing when there are no listeners to be notified
od = oi.next();
ni = newones.iterator();

if (listeners.length == 0) {
continue;
}

List<WebcamDevice> tmpnew = driver.getDevices();
List<WebcamDevice> tmpold = null;

try {
tmpold = getDevices(getWebcams(Long.MAX_VALUE, TimeUnit.MILLISECONDS));
} catch (TimeoutException e) {
throw new WebcamException(e);
}
while (ni.hasNext()) {

// convert to linked list due to O(1) on remove operation on
// iterator versus O(n) for the same operation in array list
nd = ni.next();

List<WebcamDevice> oldones = new LinkedList<WebcamDevice>(tmpold);
List<WebcamDevice> newones = new LinkedList<WebcamDevice>(tmpnew);
// remove both elements, if device name is the same, which
// actually means that device is exactly the same

Iterator<WebcamDevice> oi = oldones.iterator();
Iterator<WebcamDevice> ni = null;
if (nd.getName().equals(od.getName())) {
ni.remove();
oi.remove();
break;
}
}
}

WebcamDevice od = null; // old device
WebcamDevice nd = null; // new device
// if any left in old ones it means that devices has been removed
if (oldones.size() > 0) {

// reduce lists
List<Webcam> notified = new ArrayList<Webcam>();

while (oi.hasNext()) {
for (WebcamDevice device : oldones) {
for (Webcam webcam : webcams) {
if (webcam.getDevice().getName().equals(device.getName())) {
notified.add(webcam);
break;
}
}
}

od = oi.next();
ni = newones.iterator();
setCurrentWebcams(tmpnew);

while (ni.hasNext()) {
for (Webcam webcam : notified) {
notifyWebcamGone(webcam, listeners);
webcam.dispose();
}
}

nd = ni.next();
// if any left in new ones it means that devices has been added
if (newones.size() > 0) {

// remove both elements, if device name is the same, which
// actually means that device is exactly the same
setCurrentWebcams(tmpnew);

if (nd.getName().equals(od.getName())) {
ni.remove();
oi.remove();
for (WebcamDevice device : newones) {
for (Webcam webcam : webcams) {
if (webcam.getDevice().getName().equals(device.getName())) {
notifyWebcamFound(webcam, listeners);
break;
}
}
}
}
}

// if any left in old ones it means that devices has been removed
if (oldones.size() > 0) {
@Override
public void run() {

List<Webcam> notified = new ArrayList<Webcam>();
// do not run if driver does not support discovery

for (WebcamDevice device : oldones) {
for (Webcam webcam : webcams) {
if (webcam.getDevice().getName().equals(device.getName())) {
notified.add(webcam);
break;
}
}
}
if (support == null) {
return;
}

setCurrentWebcams(tmpnew);
running = true;

for (Webcam webcam : notified) {
notifyWebcamGone(webcam, listeners);
webcam.dispose();
}
}
// wait initial time interval since devices has been initially
// discovered

// if any left in new ones it means that devices has been added
if (newones.size() > 0) {
Object monitor = new Object();

setCurrentWebcams(tmpnew);
do {

for (WebcamDevice device : newones) {
for (Webcam webcam : webcams) {
if (webcam.getDevice().getName().equals(device.getName())) {
notifyWebcamFound(webcam, listeners);
break;
}
synchronized (monitor) {
try {
monitor.wait(support.getScanInterval());
} catch (InterruptedException e) {
if (LOG.isTraceEnabled()) {
LOG.error("Interrupted", e);
}
break;
} catch (Exception e) {
throw new RuntimeException("Problem waiting on monitor", e);
}
}

scan();

} while (running);
}

Expand Down

0 comments on commit 9f001b8

Please sign in to comment.