Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        /// <summary>
        /// フォーマットサイズの設定
        /// </summary>
        /// <param name="pin">ピン</param>
        /// <param name="width">幅 [0,1~]</param>
        /// <param name="height">高さ [0,1~]</param>
        /// <remarks>
        ///		width,height に 0,0 が指定されている場合は既定値を使用する.
        ///		それ以外は、VIDEOINFOHEADER を書き換えて SetFormat を行う.
        ///		http://msdn.microsoft.com/ja-jp/library/cc353344.aspx
        /// </remarks>
        public static void SetFormatSize(IPin pin, int width, int height)
        {
            if (width <= 0 || height <= 0)
            {
                return;
            }

            #region 手段1) IAMStreamConfig.GetNumberOfCapabilities で列挙して、該当する AM_MEDIA_TYPE を SetFormat する方法.
            if (pin is IAMStreamConfig)
            {
                var config = (IAMStreamConfig)pin;
                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++)
                    {
                        var    mt   = new AM_MEDIA_TYPE();
                        var    vih  = new VIDEOINFOHEADER();
                        IntPtr addr = IntPtr.Zero;

                        try
                        {
                            addr = Marshal.AllocCoTaskMem(size);
                            int status = config.GetStreamCaps(i, ref mt, addr);
                            if (status == (int)HRESULT.S_OK &&
                                GUID.Compare(mt.majortype.ToString(), GUID.MEDIATYPE_Video) &&
                                GUID.Compare(mt.formattype.ToString(), GUID.FORMAT_VideoInfo) &&
                                mt.cbFormat >= Marshal.SizeOf(vih) &&
                                mt.pbFormat != IntPtr.Zero
                                )
                            {
                                vih = (VIDEOINFOHEADER)Marshal.PtrToStructure(mt.pbFormat, typeof(VIDEOINFOHEADER));

                                // --- ビデオ入力サイズの確認.
                                if (vih.bmiHeader.biWidth == width &&
                                    vih.bmiHeader.biHeight == height)
                                {
                                    config.SetFormat(mt);
                                    return;
                                }
                            }
                        }
                        finally
                        {
                            if (addr != IntPtr.Zero)
                            {
                                Marshal.FreeCoTaskMem(addr);
                            }
                            Axi.FreeMediaType(ref mt);
                        }
                    }
                }
            }
            #endregion

            #region 手段2) VIDEOINFOHEADER の Width,Height を書き換えて SetFormat を行う方法.
            //
            // この手段は、多くのカメラで有効だが、LifeCam (x86) では失敗する.
            //
            {
                AM_MEDIA_TYPE   mt         = new AM_MEDIA_TYPE();
                VIDEOINFOHEADER video_info = new VIDEOINFOHEADER();

                mt         = Axi.GetFormat(pin);
                video_info = (VIDEOINFOHEADER)Marshal.PtrToStructure(mt.pbFormat, typeof(VIDEOINFOHEADER));

                // --- ビデオ入力サイズ.
                video_info.bmiHeader.biWidth  = width;
                video_info.bmiHeader.biHeight = 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;
                //mt.lSampleSize = FVIL.Data.CFviImage.CalcHorzByte(horz, bpp) * (uint)vert;

                Marshal.StructureToPtr(video_info, mt.pbFormat, true);
                Axi.SetFormat(pin, mt);
            }
            #endregion
        }