OSDN Git Service

git-svn-id: http://svn.sourceforge.jp/svnroot/nyartoolkit/NyARToolkit/trunk@775 7cac0...
authornyatla <nyatla@7cac0a50-4618-4814-88d0-24b83990f816>
Fri, 31 Dec 2010 06:36:06 +0000 (06:36 +0000)
committerAtsuo Igarashi <atsuoigarashi@ubuntu.(none)>
Tue, 5 Apr 2011 09:17:55 +0000 (18:17 +0900)
utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/JmfCaptureDevice.java [new file with mode: 0644]
utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/JmfCaptureDeviceList.java [new file with mode: 0644]
utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/JmfCaptureListener.java [new file with mode: 0644]
utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/JmfNyARRaster_RGB.java [new file with mode: 0644]
utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/MonitorCDS.java [new file with mode: 0644]
utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/MonitorStream.java [new file with mode: 0644]

diff --git a/utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/JmfCaptureDevice.java b/utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/JmfCaptureDevice.java
new file mode 100644 (file)
index 0000000..92fd34d
--- /dev/null
@@ -0,0 +1,232 @@
+package jp.nyatla.nyartoolkit.jmf.utils;\r
+\r
+import java.awt.Dimension;\r
+\r
+import javax.media.*;\r
+import javax.media.control.*;\r
+import javax.media.format.*;\r
+import javax.media.protocol.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+\r
+/**\r
+ * 1個のキャプチャデバイスを管理するクラスです。\r
+ * キャプチャデバイスの走査(開始・停止)、プロパティの取得・設定機能を提供します。\r
+ */\r
+public class JmfCaptureDevice\r
+{\r
+       private JmfCaptureListener _capture_listener;\r
+       private MonitorStream _jmf_monitor_stream;\r
+       private Processor _jmf_processor;\r
+       private CaptureDeviceInfo _info;\r
+       private VideoFormat _capture_format;\r
+       private static final String[] _enc_str={"RGB","YUV"};   \r
+       public static final int PIXEL_FORMAT_RGB =0;// "RGB";\r
+       public static final int PIXEL_FORMAT_YUV =1;// "YUV";\r
+       public JmfCaptureDevice(CaptureDeviceInfo i_capinfo) throws NyARException\r
+       {\r
+               this._info = i_capinfo;\r
+               this._capture_format = null;\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * サポートしているフォーマットの一覧を返します。\r
+        * @return\r
+        * サポートしているフォーマットを格納した配列。\r
+        */\r
+       public Format[] getSupportFormats()\r
+       {\r
+               return this._info.getFormats();\r
+       }\r
+       /**\r
+        * 現在のキャプチャフォーマットを返します。\r
+        * @return\r
+        * 現在設定してあるフォーマット。\r
+        */\r
+       public final VideoFormat getCaptureFormat()\r
+       {\r
+               return this._capture_format;\r
+       }\r
+\r
+       /**\r
+        * 現在のキャプチャフォーマットを、指定したインデクス番号のフォーマットに指定します。\r
+        * インデクス番号は、getSupportFormatsで得られるフォーマットの一覧の番号に対応します。\r
+        * @param i_index\r
+        * サポートしているフォーマットのインデクス番号。\r
+        */\r
+       public void setCaptureFormat(int i_index)\r
+       {\r
+               this._capture_format = (VideoFormat)this._info.getFormats()[i_index];\r
+               return;\r
+       }\r
+       /**\r
+        * キャプチャ画像のフォーマットを指定した形式にしようと試みます。\r
+        * @param i_encode\r
+        * キャプチャする画像フォーマットを指定します。フォーマットはこのクラスに宣言される定数値を使ってください。\r
+        * @param i_size\r
+        * キャプチャ画像サイズを指定します。\r
+        * @param i_rate\r
+        * キャプチャレートをFPS単位で指定します。\r
+        * @return\r
+        * 指定に成功するとTRUEを返します。失敗するとFALSEを返します。\r
+        */     \r
+       protected boolean setCaptureFormat(int i_encode, Dimension i_size, float i_rate) throws NyARException\r
+       {\r
+               if (this._jmf_processor != null){\r
+                       throw new NyARException();\r
+               }\r
+               Format[] formats = this._info.getFormats();\r
+               VideoFormat f = new VideoFormat(_enc_str[i_encode], i_size, Format.NOT_SPECIFIED, null, i_rate);\r
+               for (int i = 0; i < formats.length; i++){\r
+                       if (formats[i].matches(f)) {\r
+                               //[暫定実装]RGBの場合のみ、24bit-BGRAを強制する。他のフォーマットも取りたいときは要改造\r
+                               //これはMacOSのJMF等で問題が出るかもしれない。問題が出たら教えて下さい。\r
+                               if(formats[i] instanceof RGBFormat){\r
+                                       RGBFormat fmt_ref=(RGBFormat)formats[i];\r
+                                       if(fmt_ref.getBitsPerPixel()!=24 || fmt_ref.getBlueMask()!=1 || fmt_ref.getGreenMask()!=2 || fmt_ref.getRedMask()!=3){\r
+                                               continue;\r
+                                       }\r
+                               }\r
+                               f =(VideoFormat)formats[i].intersects(f);\r
+                               this._capture_format = null;\r
+                               this._capture_format = f;\r
+                               return true;\r
+                       }\r
+               }\r
+               //ない。\r
+               return false;\r
+       }\r
+       /**\r
+        * キャプチャ画像のエンコード、サイズ、レートを引数とするsetCaptureFormat関数です。\r
+        * @param i_encode\r
+        * PIXEL_FORMAT_XXXで定義される定数値を指定して下さい。\r
+        * @param i_size_x\r
+        * キャプチャする画像の横幅\r
+        * @param i_size_y\r
+        * キャプチャする画像の縦幅\r
+        * @param i_rate\r
+        * フレームレート\r
+        * @return\r
+        * 関数の実行結果を真偽値で返します。\r
+        * @throws NyARException\r
+        */     \r
+       public boolean setCaptureFormat(int i_encode,int i_size_x,int i_size_y, float i_rate) throws NyARException\r
+       {\r
+               return setCaptureFormat(i_encode,new Dimension(i_size_x,i_size_y),i_rate);\r
+       }\r
+       /**\r
+        * キャプチャ画像のサイズ、レートを引数とするsetCaptureFormat関数です。\r
+        * キャプチャ画像のエンコードは、RGB→YUVの順で検索します。\r
+        * @param i_size_x\r
+        * キャプチャする画像の横幅\r
+        * @param i_size_y\r
+        * キャプチャする画像の縦幅\r
+        * @param i_rate\r
+        * フレームレート\r
+        * @return\r
+        * 関数の実行結果を真偽値で返します。\r
+        * @throws NyARException\r
+        */\r
+       public boolean setCaptureFormat(int i_size_x,int i_size_y, float i_rate) throws NyARException\r
+       {\r
+               Dimension d=new Dimension(i_size_x,i_size_y);\r
+               if(setCaptureFormat(PIXEL_FORMAT_RGB,d,i_rate)){\r
+                       return true;\r
+               }\r
+               if(setCaptureFormat(PIXEL_FORMAT_YUV,d,i_rate)){\r
+                       return true;\r
+               }\r
+               return false;\r
+       }\r
+\r
+       \r
+       \r
+       /**\r
+        * 画像のキャプチャイベントを受信するリスナクラスを指定します。\r
+        * @param i_listener\r
+        * リスナークラス\r
+        * @throws NyARException\r
+        */\r
+       public void setOnCapture(JmfCaptureListener i_listener) throws NyARException\r
+       {\r
+               if (this._jmf_processor != null) {\r
+                       throw new NyARException();\r
+               }\r
+               this._capture_listener = i_listener;\r
+               return;\r
+       }\r
+       /**\r
+        * キャプチャーを開始します。stop関数を呼び出すまでの間、setOnCaptureで指定したリスナークラスに、\r
+        * フォーマットで指定したキャプチャ画像が通知されます。\r
+        * @throws NyARException\r
+        */\r
+       public void start() throws NyARException\r
+       {\r
+               // startしていたらエラー\r
+               if (this._jmf_processor != null) {\r
+                       throw new NyARException();\r
+               }\r
+               DataSource ds;\r
+               final MediaLocator ml = this._info.getLocator();\r
+               try {\r
+                       ds = Manager.createDataSource(ml);\r
+                       ds.connect();\r
+                       // ここでフォーマットを作成\r
+                       if (ds instanceof CaptureDevice) {\r
+                               FormatControl[] fcs = ((CaptureDevice) ds).getFormatControls();\r
+                               if (fcs.length < 1) {\r
+                                       return;\r
+                               }\r
+                               FormatControl fc = fcs[0];\r
+                               fc.setFormat(this._capture_format);\r
+                       }\r
+               } catch (Exception e) {\r
+                       throw new NyARException(e);\r
+               }\r
+               try{\r
+                       if(ds==null){\r
+                               //Merge the data sources, if both audio and video are available\r
+                               ds = Manager.createMergingDataSource(new DataSource[] { null });                                \r
+                       }else{\r
+                               // Create the monitoring datasource wrapper\r
+                               ds = new MonitorCDS(ds);                                \r
+                       }\r
+               }catch(IncompatibleSourceException e){\r
+                       throw new NyARException(e);\r
+               }\r
+               \r
+               // データソース完成\r
+               try {\r
+                       // Merge the data sources, if both audio and video are available\r
+                       VideoFormat[] formats = new VideoFormat[] { new VideoFormat(null) };\r
+                       ProcessorModel pm = new ProcessorModel(ds, formats, null);// ,\r
+                       Processor processor;\r
+                       processor = Manager.createRealizedProcessor(pm);\r
+                       this._jmf_monitor_stream = (MonitorStream) ds.getControl("jmfsample.MonitorStream");\r
+                       this._jmf_monitor_stream.setCaptureListener(this._capture_listener);\r
+                       this._jmf_processor = processor;\r
+                       this._jmf_processor.start();\r
+               } catch (Exception e) {\r
+                       ds.disconnect();\r
+                       throw new NyARException(e);\r
+               }\r
+               return;\r
+       }\r
+\r
+       public void stop()\r
+       {\r
+               this._jmf_processor.stop();\r
+               this._jmf_processor.close();\r
+               this._jmf_processor = null;\r
+               return;\r
+       }\r
+       protected void finalize()\r
+       {\r
+               if (this._jmf_processor != null) {\r
+                       this._jmf_processor.stop();\r
+                       this._jmf_processor.close();\r
+                       this._jmf_processor = null;\r
+               }\r
+               return;\r
+       }\r
+}
\ No newline at end of file
diff --git a/utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/JmfCaptureDeviceList.java b/utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/JmfCaptureDeviceList.java
new file mode 100644 (file)
index 0000000..0c35b31
--- /dev/null
@@ -0,0 +1,101 @@
+package jp.nyatla.nyartoolkit.jmf.utils;\r
+\r
+import java.awt.Dimension;\r
+import java.util.Vector;\r
+\r
+import javax.media.CaptureDeviceInfo;\r
+import javax.media.CaptureDeviceManager;\r
+import javax.media.Format;\r
+import javax.media.format.*;\r
+import jp.nyatla.nyartoolkit.*;\r
+\r
+\r
+\r
+/**\r
+ * JMFキャプチャデバイスのリストを保持します。\r
+ * 複数のカメラが接続された環境では、最も初めに認識したカメラの実がアクティブになるため、\r
+ * このクラスで実際に認識できるカメラは1個だけです。\r
+ *\r
+ */\r
+public class JmfCaptureDeviceList\r
+{\r
+       private Vector<CaptureDeviceInfo> _devices;\r
+\r
+       public JmfCaptureDeviceList() throws NyARException\r
+       { \r
+               this._devices = (Vector<CaptureDeviceInfo>)(CaptureDeviceManager.getDeviceList(null).clone());\r
+               // ビデオソースのデバイスだけ残す\r
+               try {\r
+\r
+                       for (int i = 0; i < this._devices.size();) {\r
+                               CaptureDeviceInfo cdi =this._devices.elementAt(i);\r
+                               // VideoFormatもってるかな?\r
+                               if (!isCaptureDevice(cdi)) {\r
+                                       this._devices.remove(i);\r
+                                       continue;\r
+                               }\r
+                               i++;\r
+                       }\r
+               } catch (Exception e) {\r
+                       throw new NyARException(e);\r
+               }\r
+               return;\r
+       }\r
+\r
+       /**\r
+        * i_cdiがビデオキャプチャデバイスかを調べる。ようなことをする。\r
+        * \r
+        * @param i_cdi\r
+        * @return\r
+        */\r
+       private static boolean isCaptureDevice(CaptureDeviceInfo i_cdi)\r
+       {\r
+               Format[] fms = i_cdi.getFormats();\r
+               for (int i = 0; i < fms.length; i++) {\r
+                       Format f = fms[i];\r
+                       if (f instanceof VideoFormat) {\r
+                               return true;\r
+                       }\r
+               }\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * 使用できるキャプチャデバイスの数を数える\r
+        * @return\r
+        * キャプチャデバイスの数を返却する。\r
+        */\r
+       public int getCount()\r
+       {\r
+               return this._devices.size();\r
+       }\r
+       /**\r
+        * i_index番目のキャプチャデバイスを得る。\r
+        * @param i_index\r
+        * @return\r
+        * @throws NyARException\r
+        */\r
+       public JmfCaptureDevice getDevice(int i_index) throws NyARException\r
+       {\r
+               return new JmfCaptureDevice((CaptureDeviceInfo) this._devices.elementAt(i_index));\r
+       }\r
+\r
+       public static void main(String[] args)\r
+       {\r
+               //テストケース\r
+               try {\r
+                       JmfCaptureDeviceList j = new JmfCaptureDeviceList();\r
+                       System.out.println(j.getCount());\r
+                       JmfCaptureDevice d = j.getDevice(0);\r
+                       d.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_RGB, new Dimension(320, 240), 15.0f);\r
+//                     YUVFormat f=(YUVFormat)d.getCaptureFormat();\r
+                       d.start();\r
+                       d.stop();\r
+\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return;\r
+       }\r
+\r
+}\r
diff --git a/utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/JmfCaptureListener.java b/utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/JmfCaptureListener.java
new file mode 100644 (file)
index 0000000..69dff72
--- /dev/null
@@ -0,0 +1,36 @@
+/* \r
+ * PROJECT: NyARToolkit JMF utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.jmf.utils;\r
+\r
+import javax.media.Buffer;\r
+/**\r
+ * JMF簡易キャプチャ用のリスナクラス\r
+ *\r
+ */\r
+public interface  JmfCaptureListener{\r
+    public void onUpdateBuffer(Buffer i_buffer);\r
+}
\ No newline at end of file
diff --git a/utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/JmfNyARRaster_RGB.java b/utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/JmfNyARRaster_RGB.java
new file mode 100644 (file)
index 0000000..20ec159
--- /dev/null
@@ -0,0 +1,364 @@
+/* \r
+ * PROJECT: NyARToolkit JMF utilities.\r
+ * --------------------------------------------------------------------------------\r
+ * The MIT License\r
+ * Copyright (c) 2008 nyatla\r
+ * airmail(at)ebony.plala.or.jp\r
+ * http://nyatla.jp/nyartoolkit/\r
+ * \r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ * \r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ * \r
+ */\r
+package jp.nyatla.nyartoolkit.jmf.utils;\r
+\r
+import javax.media.format.*;\r
+import javax.media.*;\r
+import java.awt.Dimension;\r
+import com.sun.media.codec.video.colorspace.*;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
+import jp.nyatla.nyartoolkit.core.rasterreader.*;\r
+import jp.nyatla.nyartoolkit.core.types.*;\r
+import jp.nyatla.nyartoolkit.core.param.*;\r
+\r
+\r
+\r
+\r
+/**\r
+ * \r
+ * RGB形式のJMFバッファをラップするNyARRasterです。\r
+ * JMFから得たラスタデータのピクセル並び順を考慮します。\r
+ *\r
+ */\r
+public class JmfNyARRaster_RGB implements INyARRgbRaster\r
+{\r
+       private JmfRGB24RasterHolder _holder;\r
+       protected NyARIntSize _size;\r
+       /**\r
+        * コンストラクタ。i_fmtに合致するバッファを持つインスタンスを作成します。\r
+        * このコンストラクタで作成したクラスは、hasBuffer()がfalseを返すことがあります。\r
+        * @param i_fmt\r
+        * @throws NyARException\r
+        */\r
+       public JmfNyARRaster_RGB(VideoFormat i_fmt) throws NyARException\r
+       {\r
+               initMember(i_fmt);\r
+       }       \r
+\r
+       private void initMember(VideoFormat i_fmt) throws NyARException\r
+       {\r
+               final Dimension s = i_fmt.getSize();\r
+               this._size= new NyARIntSize(s.width,s.height);\r
+               // データ配列の確認\r
+               if(i_fmt instanceof YUVFormat){\r
+                       //YUVフォーマット\r
+                       this._holder=new NyARGLPixelReader_YUV(this._size,(YUVFormat)i_fmt);                    \r
+               }else if(i_fmt instanceof RGBFormat){\r
+                       //RGBフォーマット\r
+                       this._holder=new NyARGLPixelReader_RGB24(this._size,(RGBFormat)i_fmt);\r
+               }else{\r
+                       throw new NyARException();\r
+               }               \r
+       }\r
+       public void setBuffer(javax.media.Buffer i_buffer) throws NyARException\r
+       {\r
+               this._holder.setMediaBuffer(i_buffer);\r
+               return;\r
+       }\r
+       final public int getWidth()\r
+       {\r
+               return this._size.w;\r
+       }\r
+\r
+       final public int getHeight()\r
+       {\r
+               return this._size.h;\r
+       }\r
+\r
+       final public NyARIntSize getSize()\r
+       {\r
+               return this._size;\r
+       }\r
+       final public int getBufferType()\r
+       {\r
+               return this._holder.buffer_type;\r
+       }\r
+       final public INyARRgbPixelReader getRgbPixelReader()\r
+       {\r
+               return this._holder;\r
+       }\r
+       /**\r
+        * インスタンスがバッファを所有するかを返します。\r
+        * @return\r
+        */     \r
+       final public boolean hasBuffer()\r
+       {\r
+               return this._holder.buffer!=null;\r
+       }\r
+       final public Object getBuffer()\r
+       {\r
+               assert(this._holder.buffer!=null);\r
+               return this._holder.buffer;\r
+       }\r
+       final public boolean isEqualBufferType(int i_type_value)\r
+       {\r
+               return this._holder.buffer_type==i_type_value;\r
+       }\r
+       final public void wrapBuffer(Object i_ref_buf) throws NyARException\r
+       {\r
+               NyARException.notImplement();\r
+       }\r
+}\r
+\r
+\r
+/**\r
+ * JMFと汎用バッファを中継する拡張INyARRgbPixelReader\r
+ * @author nyatla\r
+ *\r
+ */\r
+abstract class JmfRGB24RasterHolder implements INyARRgbPixelReader\r
+{\r
+       public int buffer_type;\r
+       public byte[] buffer;\r
+       public abstract void setMediaBuffer(javax.media.Buffer i_buffer);\r
+}\r
+\r
+/**\r
+ * RGB24フォーマットのデータを扱うピクセルリーダ\r
+ */\r
+class NyARGLPixelReader_RGB24 extends JmfRGB24RasterHolder\r
+{\r
+       protected boolean _is_flipped;\r
+       private NyARIntSize _ref_size;\r
+       public NyARGLPixelReader_RGB24(NyARIntSize i_ref_size,RGBFormat i_input_format) throws NyARException\r
+       {\r
+               this._ref_size=i_ref_size;\r
+               //ピクセルフォーマットを設定(現状は24bitRGBを受けつける。)\r
+               RGBFormat fm=(RGBFormat)i_input_format;\r
+               if(fm.getBitsPerPixel()!=24){\r
+                       throw new NyARException();\r
+               }\r
+               int r=fm.getRedMask();\r
+               int b=fm.getBlueMask();\r
+               if(r==1 && b==3){\r
+                       this.buffer_type=NyARBufferType.BYTE1D_R8G8B8_24;\r
+               }else if(r==3 && b==1){\r
+                       this.buffer_type=NyARBufferType.BYTE1D_B8G8R8_24;                       \r
+               }else{\r
+                       throw new NyARException();\r
+               }\r
+               //vertical反転の有無を確認\r
+               this._is_flipped=i_input_format.getFlipped()!=0?true:false;\r
+               this.buffer=new byte[i_ref_size.w*i_ref_size.h*3];\r
+               //RGBフォーマット\r
+               \r
+               return;\r
+       }\r
+       public void setMediaBuffer(javax.media.Buffer i_buffer)\r
+       {\r
+               //vertical反転が必要ならば、反転した画像を作成する。\r
+               byte[] src=(byte[])i_buffer.getData();\r
+               if(this._is_flipped){\r
+                       final int length = this._ref_size.w * 3;\r
+                       int src_idx = 0;\r
+                       int dest_idx = (this._ref_size.h - 1) * length;                 \r
+                       for (int i = 0; i < this._ref_size.h; i++) {\r
+                               System.arraycopy(src,src_idx, this.buffer, dest_idx, length);\r
+                               src_idx += length;\r
+                               dest_idx -= length;\r
+                       }\r
+               }else{\r
+                       System.arraycopy(src,0,this.buffer,0,this.buffer.length);\r
+                       this.buffer=(byte[])i_buffer.getData();\r
+               }\r
+               return;\r
+       }\r
+       public void getPixel(int i_x, int i_y, int[] o_rgb) throws NyARException\r
+       {\r
+               int bp = (i_x + i_y * this._ref_size.w) * 3;\r
+               byte[] ref = this.buffer;\r
+               switch(this.buffer_type){\r
+               case NyARBufferType.BYTE1D_R8G8B8_24:\r
+                       o_rgb[0] = (ref[bp + 0] & 0xff);// R\r
+                       o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
+                       o_rgb[2] = (ref[bp + 2] & 0xff);// B\r
+                       break;\r
+               case NyARBufferType.BYTE1D_B8G8R8_24:\r
+                       o_rgb[0] = (ref[bp + 2] & 0xff);// B\r
+                       o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
+                       o_rgb[2] = (ref[bp + 0] & 0xff);// R\r
+                       break;\r
+               default:\r
+                       throw new NyARException();\r
+               }\r
+               return;\r
+       }\r
+       public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) throws NyARException\r
+       {\r
+               int width = this._ref_size.w;\r
+               byte[] ref = this.buffer;\r
+               int bp;\r
+               switch(this.buffer_type){\r
+               case NyARBufferType.BYTE1D_R8G8B8_24:\r
+                       for (int i = i_num - 1; i >= 0; i--) {\r
+                               bp = (i_x[i] + i_y[i] * width) * 3;\r
+                               o_rgb[i * 3 + 0] = (ref[bp + 0] & 0xff);// R\r
+                               o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
+                               o_rgb[i * 3 + 2] = (ref[bp + 2] & 0xff);// B\r
+                       }\r
+                       break;\r
+               case NyARBufferType.BYTE1D_B8G8R8_24:\r
+                       for (int i = i_num - 1; i >= 0; i--) {\r
+                               bp = (i_x[i] + i_y[i] * width) * 3;\r
+                               o_rgb[i * 3 + 0] = (ref[bp + 2] & 0xff);// B\r
+                               o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
+                               o_rgb[i * 3 + 2] = (ref[bp + 0] & 0xff);// R\r
+                       }\r
+                       break;\r
+               default:\r
+                       throw new NyARException();\r
+               }\r
+               return;\r
+       }\r
+       public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void setPixel(int iX, int iY, int iR, int iG, int iB)throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }       \r
+       public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void switchBuffer(Object i_ref_object) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+ * ソースがYUVフォーマットのデータをBGR24として扱うピクセルリーダ\r
+ * ソースデータをセットした時に変換します。\r
+ * (将来YUVをそのまま素通りさせるように書き換えるかも)\r
+ */\r
+class NyARGLPixelReader_YUV extends JmfRGB24RasterHolder\r
+{\r
+       private NyARIntSize _ref_size;  \r
+       private YUVToRGB _yuv2rgb;\r
+\r
+       private javax.media.Buffer _rgb_buf;\r
+       /**\r
+        * フォーマットアレイから、BGR24フォーマットを探す\r
+        * @param i_formats\r
+        * @return\r
+        */\r
+       private Format pickRGB24Format(Format[] i_formats)\r
+       {\r
+               for(int i=0;i<i_formats.length;i++){\r
+                       RGBFormat f=(RGBFormat)i_formats[i];\r
+                       if(f.getBitsPerPixel()!=24){\r
+                               continue;\r
+                       }\r
+                       if(f.getRedMask()!=3 ||f.getGreenMask()!=2 ||f.getBlueMask()!=1 || f.getFlipped()!=0)\r
+                       {\r
+                               continue;\r
+                       }\r
+                       return f;\r
+               }\r
+               return null;\r
+       }\r
+       public NyARGLPixelReader_YUV(NyARIntSize i_ref_size,YUVFormat i_input_format) throws NyARException\r
+       {\r
+               this._ref_size=i_ref_size;\r
+               this.buffer_type=NyARBufferType.BYTE1D_B8G8R8_24;\r
+               this.buffer=null;\r
+               this._yuv2rgb=new YUVToRGB();\r
+               this._rgb_buf=new javax.media.Buffer();\r
+               //24bit-BGRフォーマットのものを探す\r
+               Format output_format=pickRGB24Format(this._yuv2rgb.getSupportedOutputFormats(i_input_format));\r
+               if(output_format==null){\r
+                       throw new NyARException();\r
+               }\r
+               this._yuv2rgb.setInputFormat(i_input_format);\r
+               this._yuv2rgb.setOutputFormat(output_format);\r
+               try{\r
+                       this._yuv2rgb.open();\r
+               }catch(Exception e){\r
+                       throw new NyARException();\r
+               }\r
+               return;\r
+       }\r
+       public void setMediaBuffer(javax.media.Buffer i_buffer)\r
+       {\r
+               //エラー出した時のトラップ\r
+               if(this._yuv2rgb.process(i_buffer, this._rgb_buf)!=YUVToRGB.BUFFER_PROCESSED_OK){\r
+                       System.err.println("YUVToRGB.process error:");\r
+               }\r
+               this.buffer=(byte[])this._rgb_buf.getData();\r
+               return;\r
+       }\r
+       public void getPixel(int i_x, int i_y, int[] o_rgb) throws NyARException\r
+       {\r
+               //IN :BGRBGR\r
+               //   :012012\r
+               final int bp = (i_x + i_y * this._ref_size.w) * 3;\r
+               final byte[] ref = this.buffer;\r
+               o_rgb[0] = (ref[bp + 2] & 0xff);// R\r
+               o_rgb[1] = (ref[bp + 1] & 0xff);// G\r
+               o_rgb[2] = (ref[bp + 0] & 0xff);// B\r
+               return;\r
+       }\r
+       public void getPixelSet(int[] i_x, int i_y[], int i_num, int[] o_rgb) throws NyARException\r
+       {\r
+               int bp;\r
+               final int width = this._ref_size.w;\r
+               final byte[] ref = this.buffer;\r
+               for (int i = i_num - 1; i >= 0; i--) {\r
+                       bp = (i_x[i] + i_y[i] * width) * 3;\r
+                       o_rgb[i * 3 + 0] = (ref[bp + 2] & 0xff);// R\r
+                       o_rgb[i * 3 + 1] = (ref[bp + 1] & 0xff);// G\r
+                       o_rgb[i * 3 + 2] = (ref[bp + 0] & 0xff);// B\r
+               }\r
+               return;\r
+       }\r
+       public void setPixel(int i_x, int i_y, int[] i_rgb) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void setPixels(int[] i_x, int[] i_y, int i_num, int[] i_intrgb) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+       public void setPixel(int iX, int iY, int iR, int iG, int iB)throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }       \r
+       public void switchBuffer(Object i_ref_object) throws NyARException\r
+       {\r
+               NyARException.notImplement();           \r
+       }\r
+\r
+}\r
+\r
diff --git a/utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/MonitorCDS.java b/utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/MonitorCDS.java
new file mode 100644 (file)
index 0000000..16c60bd
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 1996-2001 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
+ * modify and redistribute this software in source and binary code form,
+ * provided that i) this copyright notice and license appear on all copies of
+ * the software; and ii) Licensee does not utilize the software in a manner
+ * which is disparaging to Sun.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
+ * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
+ * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
+ * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
+ * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * This software is not designed or intended for use in on-line control of
+ * aircraft, air traffic, aircraft navigation or aircraft communications; or in
+ * the design, construction, operation or maintenance of any nuclear
+ * facility. Licensee represents and warrants that it will not use or
+ * redistribute the Software for such purposes.
+ */
+package jp.nyatla.nyartoolkit.jmf.utils;
+
+import javax.media.*;
+import javax.media.protocol.*;
+import javax.media.control.*;
+
+import java.io.IOException;
+
+public class MonitorCDS extends PushBufferDataSource
+{
+
+       private PushBufferDataSource delegate = null;
+
+       private PushBufferStream[] delStreams = null;
+
+       private MonitorStream monitorStream = null;
+
+       private PushBufferStream[] monitorStreams = null;
+
+       boolean delStarted = false; // variable used by MonitorStream also
+
+       private Control[] controls;
+
+       public MonitorCDS(DataSource ds)
+       {
+               // Get the stream from the actual datasource
+               // and create a MonitorStream from it
+               // Export the MonitorControl interface of the MonitorStream
+               if (ds instanceof PushBufferDataSource) {
+                       delegate = (PushBufferDataSource) ds;
+                       delStreams = delegate.getStreams();
+                       monitorStream = new MonitorStream(delStreams[0], this);
+                       monitorStreams = new PushBufferStream[] { monitorStream };
+               }
+       }
+
+       public Object[] getControls()
+       {
+               return controls;
+       }
+
+       public Object getControl(String value)
+       {
+               if (value.equals("jmfsample.MonitorStream") || value.equals("javax.media.control.MonitorControl")){
+                       return monitorStream;
+               }else{
+                       return null;
+               }
+       }
+
+       public javax.media.CaptureDeviceInfo getCaptureDeviceInfo()
+       {
+               return ((CaptureDevice) delegate).getCaptureDeviceInfo();
+       }
+
+       public FormatControl[] getFormatControls()
+       {
+               return ((CaptureDevice) delegate).getFormatControls();
+       }
+
+       public String getContentType()
+       {
+               return delegate.getContentType();
+       }
+
+       public void connect() throws IOException
+       {
+               if (delegate == null)
+                       throw new IOException("Incompatible DataSource");
+               // Delegate is already connected
+       }
+
+       public void disconnect()
+       {
+               monitorStream.setEnabled(false);
+               delegate.disconnect();
+       }
+
+       public synchronized void start() throws IOException
+       {
+               startDelegate();
+               delStarted = true;
+       }
+
+       public synchronized void stop() throws IOException
+       {
+               if (!monitorStream.isEnabled()) {
+                       stopDelegate();
+               }
+               delStarted = false;
+       }
+
+       public Time getDuration()
+       {
+               return delegate.getDuration();
+       }
+
+       public PushBufferStream[] getStreams()
+       {
+               return monitorStreams;
+       }
+
+       void startDelegate() throws IOException
+       {
+               delegate.start();
+       }
+
+       void stopDelegate() throws IOException
+       {
+               delegate.stop();
+       }
+
+}
diff --git a/utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/MonitorStream.java b/utils/jmf/src/jp/nyatla/nyartoolkit/jmf/utils/MonitorStream.java
new file mode 100644 (file)
index 0000000..fffb35f
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 1996-2001 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
+ * modify and redistribute this software in source and binary code form,
+ * provided that i) this copyright notice and license appear on all copies of
+ * the software; and ii) Licensee does not utilize the software in a manner
+ * which is disparaging to Sun.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
+ * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
+ * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
+ * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
+ * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * This software is not designed or intended for use in on-line control of
+ * aircraft, air traffic, aircraft navigation or aircraft communications; or in
+ * the design, construction, operation or maintenance of any nuclear
+ * facility. Licensee represents and warrants that it will not use or
+ * redistribute the Software for such purposes.
+ */
+package jp.nyatla.nyartoolkit.jmf.utils;
+
+import javax.media.*;
+import javax.media.protocol.*;
+
+import javax.media.util.BufferToImage;
+import java.io.IOException;
+import java.awt.*;
+
+public class MonitorStream implements PushBufferStream, BufferTransferHandler
+{
+
+       JmfCaptureListener img_listener;
+
+       PushBufferStream actual = null;
+
+       boolean dataAvailable = false;
+
+       boolean terminate = false;
+
+       boolean enabled = false;
+
+       Object bufferLock = new Object();
+
+       Buffer cbuffer = new Buffer();
+
+       BufferTransferHandler transferHandler = null;
+
+       Component component = null;
+
+       MonitorCDS cds;
+
+       BufferToImage bti = null;
+
+       MonitorStream(PushBufferStream actual, MonitorCDS cds)
+       {
+               this.actual = actual;
+               actual.setTransferHandler(this);
+               this.cds = cds;
+       }
+
+       public javax.media.Format getFormat()
+       {
+               return actual.getFormat();
+       }
+
+       /**
+        * 非同期READ
+        */
+       public void read(Buffer buffer) throws IOException
+       {
+               // Wait for data to be available
+               // Doesn't get used much because the transferData
+               // call is made when data IS available. And most
+               // Processors/Players read the data in the same
+               // thread that called transferData, although that's
+               // not a safe assumption to make
+               if (!dataAvailable) {
+                       synchronized (bufferLock) {
+                               while (!dataAvailable && !terminate) {
+                                       try {
+                                               bufferLock.wait(100);
+                                       } catch (InterruptedException ie) {
+                                       }
+                               }
+                       }
+               }
+
+               if (dataAvailable) {
+                       synchronized (bufferLock) {
+                               // Copy the buffer attributes, but swap the data
+                               // attributes so that no extra copy is made.
+                               buffer.copy(cbuffer, true);
+                               //dataAvailable = false;
+                       }
+               }
+               //      return;
+       }
+
+       public void setCaptureListener(JmfCaptureListener i_listener)
+       {
+               img_listener = i_listener;
+       }
+
+       public void transferData(PushBufferStream pbs)
+       {
+               // Get the data from the original source stream
+               synchronized (bufferLock) {
+                       try {
+                               pbs.read(cbuffer);
+                       } catch (IOException ioe) {
+                               return;
+                       }
+                       dataAvailable = true;
+                       bufferLock.notifyAll();
+               }
+               if (img_listener != null) {
+                       img_listener.onUpdateBuffer(cbuffer);
+               }
+
+               // Maybe synchronize this with setTransferHandler() ?
+               if (transferHandler != null && cds.delStarted)
+                       transferHandler.transferData(this);
+       }
+
+       public void setTransferHandler(BufferTransferHandler transferHandler)
+       {
+               this.transferHandler = transferHandler;
+       }
+
+       public boolean setEnabled(boolean value)
+       {
+               enabled = value;
+               if (value == false) {
+                       if (!cds.delStarted) {
+                               try {
+                                       cds.stopDelegate();
+                               } catch (IOException ioe) {
+                               }
+                       }
+               } else {
+                       // Start the capture datasource if the monitor is enabled
+                       try {
+                               cds.startDelegate();
+                       } catch (IOException ioe) {
+                       }
+               }
+               return enabled;
+       }
+
+       public boolean isEnabled()
+       {
+               return enabled;
+       }
+
+       public float setPreviewFrameRate(float rate)
+       {
+               System.err.println("TODO");
+               return rate;
+       }
+
+       public ContentDescriptor getContentDescriptor()
+       {
+               return actual.getContentDescriptor();
+       }
+
+       public long getContentLength()
+       {
+               return actual.getContentLength();
+       }
+
+       public boolean endOfStream()
+       {
+               return actual.endOfStream();
+       }
+
+       public Object[] getControls()
+       {
+               return new Object[0];
+       }
+
+       public Object getControl(String str)
+       {
+               return null;
+       }
+
+}