/// <summary> /// ICloneable の実装: インスタンスのクローンの生成 /// </summary> /// <returns> /// 自身のクローンを返します。 /// </returns> public virtual CxDSCameraParam Clone() { var clone = new CxDSCameraParam(); clone.CopyFrom(this); return(clone); }
/// <summary> /// OK ボタンが押下されたとき /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void toolOK_Click(object sender, EventArgs e) { if (this.Param == null) { this.Param = new CxDSCameraParam(); } this.Param.CopyFrom(this.Backup); this.DialogResult = System.Windows.Forms.DialogResult.OK; this.Close(); }
/// <summary> /// 画像入力フィルタの生成 /// </summary> /// <param name="param">イメージグラバーパラメータ</param> /// <returns> /// 生成されたインスタンスを返します。 /// </returns> internal virtual IBaseFilter CreateVideoCapture(CxDSCameraParam param) { IBaseFilter capture = DSLab.Axi.CreateFilter(GUID.CLSID_VideoInputDeviceCategory, param.FilterInfo.Name, param.FilterInfo.Index); if (capture != null) { // ビデオ出力フォーマットの設定. // Width,Height に 0,0 が指定されている場合は既定値を使用する. // 指定されている場合は、VIDEOINFOHEADER を書き換えて SetFormat を行う. // // http://msdn.microsoft.com/ja-jp/library/cc353344.aspx // if (0 < param.FormatInfo.VideoSize.Width && 0 < param.FormatInfo.VideoSize.Height) { // 出力ピン. IPin pin = null; if (param.PinInfo.Name != "") pin = DSLab.Axi.FindPin(capture, param.PinInfo.Name); else pin = DSLab.Axi.FindPin(capture, 0, param.PinInfo.Direction); #region 手段1) IAMStreamConfig.GetNumberOfCapabilities で列挙して、該当する AM_MEDIA_TYPE を SetFormat する方法. if (pin is IAMStreamConfig) { IAMStreamConfig config = pin as IAMStreamConfig; int count = 0; int size = 0; config.GetNumberOfCapabilities(ref count, ref size); if (size == Marshal.SizeOf(new VIDEO_STREAM_CONFIG_CAPS())) { for (int i = 0; i < count; i++) { AM_MEDIA_TYPE media_type = new AM_MEDIA_TYPE(); VIDEOINFOHEADER video_info = new VIDEOINFOHEADER(); IntPtr addr = IntPtr.Zero; try { addr = Marshal.AllocCoTaskMem(size); int status = config.GetStreamCaps(i, ref media_type, addr); if (status == (int)HRESULT.S_OK && DS.GUID.Compare(media_type.majortype.ToString(), DS.GUID.MEDIATYPE_Video) && // Function.GuidCompare(media_type.subtype.ToString(), DS.GUID.MEDIASUBTYPE_RGB24) && DS.GUID.Compare(media_type.formattype.ToString(), DS.GUID.FORMAT_VideoInfo) && media_type.cbFormat >= Marshal.SizeOf(video_info) && media_type.pbFormat != IntPtr.Zero ) { video_info = (VIDEOINFOHEADER)Marshal.PtrToStructure(media_type.pbFormat, typeof(VIDEOINFOHEADER)); // --- ビデオ入力サイズの確認. if (video_info.bmiHeader.biWidth == param.FormatInfo.VideoSize.Width && video_info.bmiHeader.biHeight == param.FormatInfo.VideoSize.Height) { config.SetFormat(media_type); return capture; } } } finally { if (addr != IntPtr.Zero) Marshal.FreeCoTaskMem(addr); Axi.DeleteMediaType(ref media_type); } } } } #endregion #region 手段2) VIDEOINFOHEADER の Width,Height を書き換えて SetFormat を行う方法. // // この手段は、多くのカメラで有効だが、LifeCam (x86) では失敗する. // { AM_MEDIA_TYPE media_type = new AM_MEDIA_TYPE(); VIDEOINFOHEADER video_info = new VIDEOINFOHEADER(); media_type = Axi.GetFormat(pin); video_info = (VIDEOINFOHEADER)Marshal.PtrToStructure(media_type.pbFormat, typeof(VIDEOINFOHEADER)); // --- ビデオ入力サイズ. video_info.bmiHeader.biWidth = param.FormatInfo.VideoSize.Width; video_info.bmiHeader.biHeight = param.FormatInfo.VideoSize.Height; // 2013.09.18(Wed): LifeCam (x86) でエラーが発生するので試したが効果は無かった. //video_info.bmiHeader.biBitCount = (short)BppIn; // 2013.09.18(Wed): lSampleSize を変更すると LifeCam (x86) でエラーが発生する. // --- サンプルサイズ. //int horz = System.Math.Abs(param.FilterFormatInfo.VideoSize.Width); //int vert = System.Math.Abs(param.FilterFormatInfo.VideoSize.Height); //int bpp = BppIn; //media_type.lSampleSize = FVIL.Data.CFviImage.CalcHorzByte(horz, bpp) * (uint)vert; Marshal.StructureToPtr(video_info, media_type.pbFormat, true); Axi.SetFormat(pin, media_type); } #endregion } } return capture; }
/// <summary> /// コンストラクタ (パラメータ指定) /// </summary> /// <param name="param">イメージグラバーパラメータ</param> public CxDSCamera(CxDSCameraParam param) { Param = param; }
/// <summary> /// 画像入力フィルタの生成 /// </summary> /// <param name="param">イメージグラバーパラメータ</param> /// <returns> /// 生成されたインスタンスを返します。 /// </returns> internal virtual IBaseFilter CreateVideoCapture(CxDSCameraParam param) { IBaseFilter capture = DSLab.Axi.CreateFilter(GUID.CLSID_VideoInputDeviceCategory, param.FilterInfo.Name, param.FilterInfo.Index); if (capture != null) { // ビデオ出力フォーマットの設定. // Width,Height に 0,0 が指定されている場合は既定値を使用する. // 指定されている場合は、VIDEOINFOHEADER を書き換えて SetFormat を行う. // // http://msdn.microsoft.com/ja-jp/library/cc353344.aspx // if (0 < param.FormatInfo.VideoSize.Width && 0 < param.FormatInfo.VideoSize.Height) { // 出力ピン. IPin pin = null; if (param.PinInfo.Name != "") { pin = DSLab.Axi.FindPin(capture, param.PinInfo.Name); } else { pin = DSLab.Axi.FindPin(capture, 0, param.PinInfo.Direction); } #region 手段1) IAMStreamConfig.GetNumberOfCapabilities で列挙して、該当する AM_MEDIA_TYPE を SetFormat する方法. if (pin is IAMStreamConfig) { IAMStreamConfig config = pin as IAMStreamConfig; int count = 0; int size = 0; config.GetNumberOfCapabilities(ref count, ref size); if (size == Marshal.SizeOf(new VIDEO_STREAM_CONFIG_CAPS())) { for (int i = 0; i < count; i++) { AM_MEDIA_TYPE media_type = new AM_MEDIA_TYPE(); VIDEOINFOHEADER video_info = new VIDEOINFOHEADER(); IntPtr addr = IntPtr.Zero; try { addr = Marshal.AllocCoTaskMem(size); int status = config.GetStreamCaps(i, ref media_type, addr); if (status == (int)HRESULT.S_OK && DS.GUID.Compare(media_type.majortype.ToString(), DS.GUID.MEDIATYPE_Video) && // Function.GuidCompare(media_type.subtype.ToString(), DS.GUID.MEDIASUBTYPE_RGB24) && DS.GUID.Compare(media_type.formattype.ToString(), DS.GUID.FORMAT_VideoInfo) && media_type.cbFormat >= Marshal.SizeOf(video_info) && media_type.pbFormat != IntPtr.Zero ) { video_info = (VIDEOINFOHEADER)Marshal.PtrToStructure(media_type.pbFormat, typeof(VIDEOINFOHEADER)); // --- ビデオ入力サイズの確認. if (video_info.bmiHeader.biWidth == param.FormatInfo.VideoSize.Width && video_info.bmiHeader.biHeight == param.FormatInfo.VideoSize.Height) { config.SetFormat(media_type); return(capture); } } } finally { if (addr != IntPtr.Zero) { Marshal.FreeCoTaskMem(addr); } Axi.DeleteMediaType(ref media_type); } } } } #endregion #region 手段2) VIDEOINFOHEADER の Width,Height を書き換えて SetFormat を行う方法. // // この手段は、多くのカメラで有効だが、LifeCam (x86) では失敗する. // { AM_MEDIA_TYPE media_type = new AM_MEDIA_TYPE(); VIDEOINFOHEADER video_info = new VIDEOINFOHEADER(); media_type = Axi.GetFormat(pin); video_info = (VIDEOINFOHEADER)Marshal.PtrToStructure(media_type.pbFormat, typeof(VIDEOINFOHEADER)); // --- ビデオ入力サイズ. video_info.bmiHeader.biWidth = param.FormatInfo.VideoSize.Width; video_info.bmiHeader.biHeight = param.FormatInfo.VideoSize.Height; // 2013.09.18(Wed): LifeCam (x86) でエラーが発生するので試したが効果は無かった. //video_info.bmiHeader.biBitCount = (short)BppIn; // 2013.09.18(Wed): lSampleSize を変更すると LifeCam (x86) でエラーが発生する. // --- サンプルサイズ. //int horz = System.Math.Abs(param.FilterFormatInfo.VideoSize.Width); //int vert = System.Math.Abs(param.FilterFormatInfo.VideoSize.Height); //int bpp = BppIn; //media_type.lSampleSize = FVIL.Data.CFviImage.CalcHorzByte(horz, bpp) * (uint)vert; Marshal.StructureToPtr(video_info, media_type.pbFormat, true); Axi.SetFormat(pin, media_type); } #endregion } } return(capture); }
/// <summary> /// グラフの生成 /// </summary> /// <param name="output_file">出力ファイル</param> public virtual void Setup(string output_file) { this.Dispose(); try { CxDSCameraParam param = this.Param; // グラフビルダー. // CoCreateInstance GraphBuilder = (IGraphBuilder)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid(GUID.CLSID_FilterGraph))); #region フィルタ追加. // 画像入力フィルタ. IBaseFilter capture = CreateVideoCapture(param); if (capture == null) { throw new System.IO.IOException(); } this.GraphBuilder.AddFilter(capture, "CaptureFilter"); IPin capture_out = DSLab.Axi.FindPin(capture, 0, PIN_DIRECTION.PINDIR_OUTPUT); this.CaptureFilter = capture; this.CaptureOutPin = capture_out; // サンプルグラバー. IBaseFilter grabber = (IBaseFilter)CreateSampleGrabber(); if (grabber == null) { throw new System.IO.IOException(); } this.GraphBuilder.AddFilter(grabber, "SampleGrabber"); this.SampleGrabber = (ISampleGrabber)grabber; #endregion #region キャプチャビルダー: { int hr = 0; CaptureBuilder = (ICaptureGraphBuilder2)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid(GUID.CLSID_CaptureGraphBuilder2))); hr = CaptureBuilder.SetFiltergraph(GraphBuilder); if (string.IsNullOrEmpty(output_file)) { // レンダラー. IBaseFilter renderer = null; renderer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid(GUID.CLSID_NullRenderer))); if (renderer == null) { throw new System.IO.IOException(); } this.GraphBuilder.AddFilter(renderer, "Renderer"); this.Renderer = renderer; #if true // IGraphBuilder.Connect の代わりに ICaptureGraphBuilder2.RenderStream を使用する. // fig) [capture]-out->-in-[sample grabber]-out->-in-[null render] hr = CaptureBuilder.RenderStream(new Guid(GUID.PIN_CATEGORY_CAPTURE), new Guid(GUID.MEDIATYPE_Video), capture, grabber, renderer); #else // ピンの取得. IPin grabber_in = DSLab.Axi.FindPin(grabber, 0, PIN_DIRECTION.PINDIR_INPUT); IPin grabber_out = DSLab.Axi.FindPin(grabber, 0, PIN_DIRECTION.PINDIR_OUTPUT); IPin renderer_in = DSLab.Axi.FindPin(renderer, 0, PIN_DIRECTION.PINDIR_INPUT); // ピンの接続. GraphBuilder.Connect(capture_out, grabber_in); GraphBuilder.Connect(grabber_out, renderer_in); // ピンの保管. //SampleGrabberInPin = grabber_in; //SampleGrabberOutPin = grabber_out; //RendererInPin = renderer_in; #endif } else { IBaseFilter mux = null; IFileSinkFilter sync = null; hr = CaptureBuilder.SetOutputFileName(new Guid(GUID.MEDIASUBTYPE_Avi), output_file, ref mux, ref sync); hr = CaptureBuilder.RenderStream(new Guid(GUID.PIN_CATEGORY_CAPTURE), new Guid(GUID.MEDIATYPE_Video), capture, grabber, mux); this.Mux = mux; this.Sync = sync; } } #endregion #region 保管: フレームサイズ. VIDEOINFOHEADER vinfo = DSLab.Axi.GetVideoInfo(SampleGrabber); this.SampleGrabberCB.BitmapInfo = vinfo.bmiHeader; this.SampleGrabberCB.FrameSize = new Size( System.Math.Abs(this.SampleGrabberCB.BitmapInfo.biWidth), System.Math.Abs(this.SampleGrabberCB.BitmapInfo.biHeight) ); #endregion #region 保管: デバイス名称. try { if (string.IsNullOrEmpty(param.FilterInfo.Name) == false) { this.DeviceName = param.FilterInfo.Name; } else { int filter_index = param.FilterInfo.Index; List <DSLab.CxDSFilterInfo> filters = DSLab.Axi.GetFilterList(DSLab.GUID.CLSID_VideoInputDeviceCategory); if (0 <= filter_index && filter_index < filters.Count) { this.DeviceName = filters[filter_index].Name; } } } catch (System.Exception) { this.DeviceName = ""; } #endregion // DEBUG #if DEBUG DebugPrint(this.GraphBuilder); #endif } catch (Exception ex) { this.Dispose(); throw new DSLab.CxDSException(ex); } }
/// <summary> /// ICloneable の実装: インスタンスのクローンの生成 /// </summary> /// <returns> /// 自身のクローンを返します。 /// </returns> public virtual CxDSCameraParam Clone() { var clone = new CxDSCameraParam(); clone.CopyFrom(this); return clone; }
/// <summary> /// OK ボタンが押下されたとき /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void toolOK_Click(object sender, EventArgs e) { if (this.Param == null) this.Param = new CxDSCameraParam(); this.Param.CopyFrom(this.Backup); this.DialogResult = System.Windows.Forms.DialogResult.OK; this.Close(); }
/// <summary> /// フォームロード時の初期化処理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void CxDSSelectionForm_Load(object sender, EventArgs e) { if (this.Param == null) this.Param = new CxDSCameraParam(); this.Backup.CopyFrom(this.Param); this.propertyParam.SelectedObject = this.Backup; this.Grabber.Param = this.Backup; InitializeFilterPairs(); timerUpdateUI.Start(); }