OSDN Git Service

[更新]NyARToolkit/nyatlaブランチ
[nyartoolkit-and/nyartoolkit-and.git] / branches / nyatla / src.utils / jmf / jp / nyatla / nyartoolkit / jmf / utils / JmfCameraCapture.java
1 /**\r
2  * JMFお手軽キャプチャクラス\r
3  * (c)2008 A虎@nyatla.jp\r
4  * airmail@ebony.plala.or.jp\r
5  * http://nyatla.jp/\r
6  */\r
7 package jp.nyatla.nyartoolkit.jmf.utils;\r
8 \r
9 import javax.media.*;\r
10 import javax.media.protocol.*;\r
11 import javax.media.control.*;\r
12 import javax.media.format.*;\r
13 import java.awt.*;\r
14 import java.util.*;\r
15 import javax.media.protocol.DataSource;\r
16 \r
17 import jp.nyatla.nyartoolkit.core.NyARException;\r
18 \r
19 public class JmfCameraCapture\r
20 {\r
21     private Dimension image_size;\r
22 \r
23     private JmfCaptureListener capture_listener;\r
24 \r
25     // private DataSource jmf_data_source;\r
26     private MonitorStream jmf_monitor_stream;\r
27 \r
28     private Processor jmf_processor;\r
29 \r
30     private VideoFormat jmf_video_format;\r
31 \r
32     private Buffer read_buf = new Buffer();\r
33 \r
34     public static final String PIXEL_FORMAT_RGB = "RGB";\r
35 \r
36     public JmfCameraCapture(int i_width, int i_height, float i_rate,\r
37             String i_pixcel_format) {\r
38         String encoding = i_pixcel_format;// comboEncoding.getSelectedItem();\r
39         image_size = new Dimension(i_width, i_height);\r
40         jmf_video_format = new VideoFormat(encoding, image_size,\r
41                 Format.NOT_SPECIFIED, null, i_rate);\r
42     }\r
43 \r
44     public Dimension getSize() {\r
45         return image_size;\r
46     }\r
47 \r
48     public javax.media.Buffer readBuffer() throws NyARException {\r
49         if (jmf_monitor_stream == null) {\r
50             throw new NyARException();\r
51         }\r
52         try {\r
53             jmf_monitor_stream.read(read_buf);\r
54         } catch (Exception e) {\r
55             throw new NyARException(e);\r
56         }\r
57         return read_buf;\r
58     }\r
59 \r
60     public void setCaptureListener(JmfCaptureListener i_listener)\r
61             throws NyARException {\r
62         if (jmf_processor != null) {\r
63             throw new NyARException();\r
64         }\r
65         capture_listener = i_listener;\r
66 \r
67     }\r
68 \r
69     public void start() throws NyARException {\r
70 \r
71         DataSource ds = getCaptureDS(jmf_video_format);\r
72         VideoFormat[] formats = new VideoFormat[] { new VideoFormat(null) };\r
73         ProcessorModel pm = new ProcessorModel(ds, formats, null);// ,\r
74                                                                         // formats,\r
75                                                                         // ftd);\r
76         Processor processor;\r
77         try {\r
78             processor = Manager.createRealizedProcessor(pm);\r
79         } catch (Exception e) {\r
80             // Make sure the capture devices are released\r
81             ds.disconnect();\r
82             throw new NyARException(e);\r
83         }\r
84         // Get the monitor control:\r
85         // Since there are more than one MonitorControl objects\r
86         // exported by the DataSource, we get the specific one\r
87         // that is also the MonitorStream object.\r
88         jmf_monitor_stream = (MonitorStream) ds\r
89                 .getControl("jmfsample.MonitorStream");\r
90         jmf_monitor_stream.setCaptureListener(capture_listener);\r
91         // jmf_data_source=ds;\r
92         jmf_processor = processor;\r
93         jmf_processor.start();\r
94     }\r
95 \r
96     public void stop() {\r
97         jmf_processor.stop();\r
98         jmf_processor.close();\r
99         jmf_processor = null;\r
100 \r
101     }\r
102 \r
103     protected void finalize() {\r
104         if (jmf_processor != null) {\r
105             jmf_processor.stop();\r
106             jmf_processor.close();\r
107             jmf_processor = null;\r
108         }\r
109     }\r
110 \r
111     private static DataSource getCaptureDS(VideoFormat vf) {\r
112         DataSource dsVideo = null;\r
113         DataSource ds = null;\r
114 \r
115         // Create a capture DataSource for the video\r
116         // If there is no video capture device, then exit with null\r
117         if (vf != null) {\r
118             dsVideo = createDataSource(vf);\r
119             if (dsVideo == null)\r
120                 return null;\r
121         }\r
122 \r
123         // Create the monitoring datasource wrapper\r
124         if (dsVideo != null) {\r
125             dsVideo = new MonitorCDS(dsVideo);\r
126             return dsVideo;\r
127         }\r
128 \r
129         // Merge the data sources, if both audio and video are available\r
130         try {\r
131             ds = Manager.createMergingDataSource(new DataSource[] { dsVideo });\r
132         } catch (IncompatibleSourceException ise) {\r
133             return null;\r
134         }\r
135 \r
136         return ds;\r
137     }\r
138 \r
139     private static DataSource createDataSource(Format format)\r
140     {\r
141         DataSource ds;\r
142         Vector devices;\r
143         CaptureDeviceInfo cdi;\r
144         MediaLocator ml;\r
145 \r
146         // Find devices for format\r
147         devices = CaptureDeviceManager.getDeviceList(format);\r
148         if (devices.size() < 1) {\r
149             System.err.println("! No Devices for " + format);\r
150             return null;\r
151         }\r
152         // Pick the first device\r
153         cdi = (CaptureDeviceInfo) devices.elementAt(0);\r
154 \r
155         ml = cdi.getLocator();\r
156 \r
157         try {\r
158             ds = Manager.createDataSource(ml);\r
159             ds.connect();\r
160             if (ds instanceof CaptureDevice) {\r
161                 setCaptureFormat((CaptureDevice) ds, format);\r
162             }\r
163         } catch (Exception e) {\r
164             System.err.println(e);\r
165             return null;\r
166         }\r
167         return ds;\r
168     }\r
169 \r
170     private static void setCaptureFormat(CaptureDevice cdev, Format format)\r
171     {\r
172         FormatControl[] fcs = cdev.getFormatControls();\r
173         if (fcs.length < 1) {\r
174             return;\r
175         }\r
176         FormatControl fc = fcs[0];\r
177         Format[] formats = fc.getSupportedFormats();\r
178         for (int i = 0; i < formats.length; i++) {\r
179             if (formats[i].matches(format)) {\r
180                 format = formats[i].intersects(format);\r
181                 fc.setFormat(format);\r
182                 break;\r
183             }\r
184         }\r
185     }\r
186 }