blob: e52bced8faad7f6e31efc1aead7aa51255fb5071 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
package edu.wpi.first.wpijavacv;
import com.googlecode.javacv.FFmpegFrameGrabber;
import static com.googlecode.javacv.cpp.opencv_core.*;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
/**
* A class used to gather images from the robot's camera.
* @author Joe Grinstead and Greg Granito
*/
public class WPIFFmpegVideo extends WPIDisposable {
private FFmpegFrameGrabber grabber;
private IplImage image;
private boolean readImage = true;
private boolean badConnection = false;
private final Object imageLock = new Object();
private final Object grabberLock = new Object();
public WPIFFmpegVideo(final String path) {
new Thread() {
@Override
public void run() {
grabber = new FFmpegFrameGrabber(path);
grabber.setFrameRate(1.0);
try {
grabber.start();
while (!isDisposed()) {
try {
IplImage newest;
synchronized (grabberLock) {
if (isDisposed()) {
return;
}
newest = grabber.grab();
}
if (isNull(newest)) {
synchronized (imageLock) {
badConnection = true;
imageLock.notify();
}
return;
} else {
synchronized (imageLock) {
if (image == null) {
image = cvCreateImage(newest.cvSize(), newest.depth(), newest.nChannels());
}
cvCopy(newest, image);
readImage = false;
badConnection = false;
imageLock.notify();
}
}
} catch (Exception ex) {
synchronized (imageLock) {
badConnection = true;
imageLock.notify();
}
ex.printStackTrace();
return;
}
try {
Thread.sleep(20);
} catch (InterruptedException ex) {
}
}
} catch (Exception ex) {
synchronized (imageLock) {
badConnection = true;
imageLock.notify();
}
ex.printStackTrace();
}
}
}.start();
}
public WPIImage getImage() throws BadConnectionException {
validateDisposed();
synchronized (imageLock) {
if (badConnection) {
throw new BadConnectionException();
} else if (image == null) {
return null;
} else if (image.nChannels() == 1) {
return new WPIGrayscaleImage(image.clone());
} else {
assert image.nChannels() == 3;
return new WPIColorImage(image.clone());
}
}
}
public WPIImage getNewImage(double timeout) throws BadConnectionException {
validateDisposed();
synchronized (imageLock) {
readImage = true;
while (readImage && !badConnection) {
try {
badConnection = true;
imageLock.wait((long) (timeout * 1000));
} catch (InterruptedException ex) {
}
}
readImage = true;
if (badConnection) {
throw new BadConnectionException();
} else if (image.nChannels() == 1) {
return new WPIGrayscaleImage(image.clone());
} else {
assert image.nChannels() == 3;
return new WPIColorImage(image.clone());
}
}
}
public WPIImage getNewImage() throws BadConnectionException {
return getNewImage(0);
}
@Override
protected void disposed() {
try {
synchronized (imageLock) {
if (!isNull(image)) {
image.release();
}
image = null;
}
} catch (Exception ex) {
}
}
/**
* An exception that occurs when the camera can not be reached.
* @author Greg Granito
*/
public static class BadConnectionException extends Exception {
}
@Override
protected void finalize() throws Throwable {
grabber.stop();
super.finalize();
}
}
|