View Javadoc

1   /**
2    * 
3    */
4   package de.desy.acop.video;
5   
6   import java.beans.PropertyChangeListener;
7   import java.beans.PropertyChangeSupport;
8   
9   import de.desy.acop.transport.ConnectionFailed;
10  import de.desy.acop.transport.ConnectionParameters;
11  import de.desy.acop.video.analysis.AImage;
12  //import de.desy.acop.video.displayer.VideoHeaderV3; // mdavid: commented
13  import de.desy.tine.client.TCallback;
14  import de.desy.tine.client.TLink;
15  import de.desy.tine.client.TLinkCallback;
16  import de.desy.tine.dataUtils.TDataType;
17  import de.desy.tine.definitions.TAccess;
18  import de.desy.tine.definitions.TErrorList;
19  import de.desy.tine.definitions.TMode;
20  import de.desy.tine.types.IMAGE;
21  
22  /**
23   * </code>VideoServerConnection</code> provides the interface for accessing video
24   * analysis server.
25   * 
26   * @author Tilen Kusterle, Cosylab
27   *
28   */
29  public class VideoServerConnection {
30  	
31  	//FIXME add handling of precise background
32  	public static final String PROPERTY_A_IMAGE = "aImage";
33  	public static final String PROPERTY_BACKGROUND = "background";
34  	public static final String PROPERTY_PRECISE_BACKGROUND = "preciseBackground";
35  	public static final String PROPERTY_PRECISE_BACKGROUND_WIDTH = "preciseBackgroundWidth";
36  	private static final String ANALYSIS_PROPERTY = "Analysis";
37  	private static final String BACKGROUND_PROPERTY = "Background";
38  	private static final String PRECISE_BACKGROUND_PROPERTY = "PreciseBackground";
39  	private static final String BACKGROUND_ID_PROPERTY = "BackgroundId";
40  	private static final String ANALYSIS_PARAMETERS_PROPERTY = "AnalysisParameters";
41  	
42  	private class AnalysisHandler implements TLinkCallback {
43  		
44  		private TLink tlink;
45  		private boolean isTransfering;
46  		private AImage image;
47  		
48  		public AnalysisHandler() {
49  			IMAGE image = new IMAGE();
50  			this.image = new AImage(image, 0, 0, 0, 0, 
51  					0, 0, 0, 0, 0.0,
52  					new double[]{}, 0.0, 0.0, 0.0, 0.0,0.0,
53  					0.0,0.0,0.0,0.0,
54  					new double[]{}, 0.0, 0.0, 0.0, 0.0,0.0,
55  					0.0,0.0,0.0,0.0,
56  					0.0, 0.0, 0.0, 0.0, 0.0,0,true,false,true);
57  			
58  		}
59  	
60  		
61  		/* (non-Javadoc)
62  		 * @see de.desy.tine.client.TLinkCallback#callback(de.desy.tine.client.TLink)
63  		 */
64  		@Override
65  		public void callback(TLink link) {
66  			if (!isTransfering) return;
67  			if (link.getLinkStatus() != 0) {
68  				System.out.println("Link Error : code=" + link.getLinkStatus() + " msg=" + link.getLastError());
69  				return;
70  			}
71  			int id = getBackgroundId();
72  			if (backgroundId != id) {
73  				try {
74  					backgroundId = id;
75  					loadBackground();
76  					loadPreciseBackground();
77  					//TODO
78  					getPcSupport().firePropertyChange(PROPERTY_BACKGROUND, null, background);
79  					getPcSupport().firePropertyChange(PROPERTY_PRECISE_BACKGROUND,null,preciseBackground);
80  					getPcSupport().firePropertyChange(PROPERTY_PRECISE_BACKGROUND_WIDTH,null,preciseBackgroundWidth);
81  				} catch (Exception e) {
82  					e.printStackTrace();
83  				}
84  			}
85  			aImage = new AImage(this.image);
86  			getPcSupport().firePropertyChange(PROPERTY_A_IMAGE, null, aImage);
87  		}
88  		
89  		public void openLink(int accessRate) throws ConnectionFailed {
90  			TDataType dataOut = new TDataType(new AImage[]{image});
91  			tlink = new TLink(server+"/"+device, ANALYSIS_PROPERTY, dataOut, null, TAccess.CA_READ);
92  			if (tlink.attach(TMode.CM_POLL, this, accessRate) < 0) {
93  				tlink.cancel();
94  				tlink = null;
95  				throw new ConnectionFailed("No permanent connection to server (\"" + tlink.getLastError() + "\".", null);
96  			}
97  			isTransfering = true;
98  		}
99  		
100 		public void closeLink() {
101 			if (tlink != null) {
102 				tlink.cancel();
103 				tlink = null;
104 			}
105 			isTransfering = false;
106 		}
107 		
108 	}
109 	
110 	private String server = "VideoAnalysis-EQM";
111 	private String device = "Device";
112 	private int backgroundId = -1;
113 	
114 	private AnalysisHandler analysisHandler;
115 	
116 	private AImage aImage;
117 	private IMAGE background;
118 	private double[] preciseBackground;
119 	private int preciseBackgroundWidth = -1;
120 	private int accessRate = 1000;
121 	private int timeout = 1000;
122 	private boolean connected = false;
123 	
124 	private PropertyChangeSupport pcSupport;
125 	
126 	/**
127 	 * Sets the analysis parameters (threshold and region of interest) to analysis server.
128 	 * @param threshold the threshold
129 	 * @param roiX the region's starting X coordinate
130 	 * @param roiY the region's starting Y coordinate
131 	 * @param roiW the region's width
132 	 * @param roiH the region's height
133 	 * @param calculateThreshold true if the threshold should be calculated by the server or false otherwise
134 	 * @throws ConnectionFailed if unable to connect
135 	 */
136 	public void setAnalysisParameters(double threshold, int roiX, int roiY, int roiW, int roiH, int roi2X, int roi2Y, int roi2W, int roi2H, boolean calculateThreshold,boolean performFit) throws ConnectionFailed {
137 		TDataType tdt = new TDataType(new double[]{threshold, roiX, roiY, roiW, roiH,roi2X, roi2Y, roi2W,roi2H,calculateThreshold ? 1.0 : 0.0,performFit ? 1.0 : 0.0});
138 		TLink tl = new TLink(server+"/"+device, ANALYSIS_PARAMETERS_PROPERTY, null, tdt, TAccess.CA_WRITE);
139 		tl.execute(timeout, true);
140 		tl.cancel();
141 	}
142 	
143 	/**
144 	 * Sets the background image to analysis server.
145 	 * @param background the background image to set
146 	 * @throws ConnectionFailed if unable to connect
147 	 */
148 
149 	public void setBackground(IMAGE background) throws ConnectionFailed {
150 		if (background == null) {
151 			background = new IMAGE(0);
152 		}
153 		TDataType tdt = new TDataType(new IMAGE[]{background});
154 		TLink tl = new TLink(server+"/"+device, BACKGROUND_PROPERTY, null, tdt, TAccess.CA_WRITE);
155 		tl.execute(timeout, true);
156 		tl.cancel();
157 	}
158 		
159 	/**
160 	 * Gets the background image from analysis server.
161 	 * @return the background image
162 	 * @throws ConnectionFailed
163 	 */
164 	public IMAGE getBackground() {
165 		return background;
166 	}
167 	
168 	private void loadBackground() {
169 		if (background == null) {
170 			background = new IMAGE(/*VideoHeaderV3.TRANSPORT_LENGTH_V3*/); // mdavid: commented
171 		}
172 		TDataType tdt = new TDataType(new IMAGE[]{background});
173 		TLink tl = new TLink(server+"/"+device, BACKGROUND_PROPERTY, tdt, null, TAccess.CA_READ);
174 		tl.execute(timeout, true);
175 		tdt.getData(background);
176 		tl.cancel();
177 //		if (background != null && background.getFrameHeader().sourceWidth == 0 && background.getFrameHeader().sourceHeight == 0) background = null;
178 	}
179 	
180 	private void loadPreciseBackground() {
181 		//TODO put somewhere the image width;
182 		if (preciseBackground == null) {
183 			preciseBackground = new double[0];
184 		}
185 		TDataType tdt = new TDataType(preciseBackground);
186 		TLink tl = new TLink(server+"/"+device, PRECISE_BACKGROUND_PROPERTY, tdt, null, TAccess.CA_READ);
187 		tl.execute(timeout, true);
188 		tdt.getData(preciseBackground);
189 		tl.cancel();
190 	}
191 	
192 	/**
193 	 * Sets the precise background image array.
194 	 * 
195 	 * @param background the image array
196 	 * @param width the width of the image
197 	 * @throws ConnectionFailed
198 	 */
199 	public void setPreciseBackground(double[] background, int width) throws ConnectionFailed {
200 		//TODO put the width somewhere
201 		if (background == null) {
202 			background = new double[0];
203 		}
204 		TDataType tdt = new TDataType(background);
205 		TLink tl = new TLink(server+"/"+device, PRECISE_BACKGROUND_PROPERTY, null, tdt, TAccess.CA_WRITE);
206 		tl.execute(timeout, true);
207 		tl.cancel();
208 	}
209 	
210 	/**
211 	 * Returns the precise background width.
212 	 * @return precise background image width
213 	 */
214 	public int getPreciseBackgroundWidth() {
215 		return preciseBackgroundWidth;
216 	}
217 	
218 	/**
219 	 * Returns the precise background array.
220 	 * 
221 	 * @return the precise background
222 	 */
223 	public double[] getPreciseBackground() {
224 		return preciseBackground;
225 	}
226 	
227 	public int getBackgroundId() {
228 		int[] result = new int[] {-1};
229 		TDataType tdt = new TDataType(result);
230 		TLink tl = new TLink(server+"/"+device, BACKGROUND_ID_PROPERTY, tdt, null, TAccess.CA_READ);
231 		tl.execute(timeout, true);
232 		tl.cancel();
233 		return result[0];
234 	}
235 	
236 	/**
237 	 * Connects this </code>VideoServerConnection</code> to video analysis server.
238 	 * @throws ConnectionFailed if unable to connect
239 	 */
240 	public void connect() throws ConnectionFailed {
241 		if (connected) return;
242 		getAnalysisHandler().openLink(accessRate);
243 		connected = true;
244 	}
245 	
246 	/**
247 	 * Disconnects this </code>VideoServerConnection</code> from video analysis server.
248 	 */
249 	public void disconnect() {
250 		if (!connected) return;
251 		getAnalysisHandler().closeLink();
252 		connected = false;
253 	}
254 	
255 	public void setConnectionParameters(ConnectionParameters cp) {
256 		disconnect();
257 		server = cp.getDeviceGroup();
258 		device = cp.getDeviceName();
259 		accessRate = cp.getAccessRate();
260 	}
261 	
262 	/**
263 	 * Gets the selected access rate.
264 	 * @return the selected access rate
265 	 */
266 	public int getAccessRate() {
267 		return accessRate;
268 	}
269 	
270 	public void setAccessRate(int accessRate) {
271 		if (this.accessRate == accessRate) return;
272 		this.accessRate = accessRate;
273 		if (connected) {
274 			disconnect();
275 			try {
276 				connect();
277 			} catch (ConnectionFailed e) {
278 				e.printStackTrace();
279 			}
280 		}
281 		
282 	}
283 	
284 	/**
285 	 * Gets current </code>AImage</code>.
286 	 * @return current </code>AImage</code>
287 	 */
288 	public AImage getAImage() {
289 		return aImage;
290 	}
291 	
292 	private AnalysisHandler getAnalysisHandler() {
293 		if (analysisHandler == null) {
294 			analysisHandler = new AnalysisHandler();
295 		}
296 		return analysisHandler;
297 	}
298 	
299 	private PropertyChangeSupport getPcSupport() {
300 		if (pcSupport == null) {
301 			pcSupport = new PropertyChangeSupport(this);
302 		}
303 		return pcSupport;
304 	}
305 	
306 	/**
307 	 * Adds a </code>PropertyChangeListener</code> for the specified propertyName.
308 	 * @param propertyName the name of the property
309 	 * @param listener the </code>PropertyChangeListener</code> to add
310 	 */
311 	public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
312 		getPcSupport().addPropertyChangeListener(propertyName, listener);
313 	}
314 	
315 	/**
316 	 * Removes a </code>PropertyChangeListener</code> for the specified propertyName.
317 	 * @param propertyName the name of the property
318 	 * @param listener the </code>PropertyChangeListener</code> to remove
319 	 */
320 	public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
321 		getPcSupport().removePropertyChangeListener(propertyName, listener);
322 	}
323 	
324 	/**
325 	 * Adds a </code>PropertyChangeListener</code>.
326 	 * @param listener the </code>PropertyChangeListener</code> to add
327 	 */
328 	public void addPropertyChangeListener(PropertyChangeListener listener) {
329 		getPcSupport().addPropertyChangeListener(listener);
330 	}
331 	
332 	/**
333 	 * Removes a </code>PropertyChangeListener</code>.
334 	 * @param listener the </code>PropertyChangeListener</code> to remove
335 	 */
336 	public void removePropertyChangeListener(PropertyChangeListener listener) {
337 		getPcSupport().removePropertyChangeListener(listener);
338 	}	
339 	
340 	public static void main(String[] args) {
341 		final IMAGE image = new IMAGE();
342 		final AImage aImage = new AImage(image, 0, 0, 0, 0, 0, 0, 0, 0, 0.0,
343 				new double[]{}, 0.0, 0.0, 0.0, 0.0,0.0,
344 				0.0,0.0,0.0,0.0,
345 				new double[]{}, 0.0, 0.0, 0.0, 0.0,0.0,
346 				0.0,0.0,0.0,0.0,
347 				0.0, 0.0, 0.0, 0.0, 0.0,0,true,false,true);
348 		TDataType dataOut = new TDataType(aImage);
349 		TLink tlink = new TLink("/TEST/VideoAnalysis-EQM/Device", "Analysis", dataOut, null, TAccess.CA_READ);
350 		int c = tlink.attach(TMode.CM_POLL, new TCallback(){
351 			@Override
352 			public void callback(int LinkIndex, int LinkStatus) {
353 				System.out.println(LinkIndex + " " + TErrorList.toString(LinkStatus));
354 				System.out.println(aImage);
355 			}
356 		}, 1000);
357 		System.out.println(c);
358 	}
359 }