--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+/* \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
--- /dev/null
+/* \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
--- /dev/null
+/*
+ * 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();
+ }
+
+}
--- /dev/null
+/*
+ * 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;
+ }
+
+}