Exemplo n.º 1
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
        }
Exemplo n.º 2
0
        /// <summary>
        /// フォーマット一覧の取得
        /// </summary>
        /// <param name="pin">対象のピン</param>
        /// <returns>
        ///		取得したフォーマット情報のコレクションを返します。
        /// </returns>
        public static List <CxFormatInfo> GetFormatList(IPin pin)
        {
            var result = new List <CxFormatInfo>();

            if (pin == null)
            {
                return(result);
            }

            var config = pin as IAMStreamConfig;

            if (config == null)
            {
                return(result);
            }

            IntPtr dataptr = IntPtr.Zero;

            try
            {
                int count = 0;
                int size  = 0;
                config.GetNumberOfCapabilities(ref count, ref size);

                dataptr = Marshal.AllocHGlobal(size);

                for (int i = 0; i < count; i++)
                {
                    AM_MEDIA_TYPE mt = null;

                    try
                    {
                        config.GetStreamCaps(i, ref mt, dataptr);

                        // 基本情報の取得.
                        var info = new CxFormatInfo();
                        info.MediaType    = GUID.Normalize(mt.majortype.ToString());
                        info.MediaSubType = GUID.Normalize(mt.subtype.ToString());
                        info.FormatType   = GUID.Normalize(mt.formattype.ToString());

                        // 映像形式か否か.
                        if (GUID.Compare(info.FormatType, GUID.FORMAT_VideoInfo))
                        {
                            var vih = new VIDEOINFOHEADER();
                            vih            = (VIDEOINFOHEADER)Marshal.PtrToStructure(mt.pbFormat, typeof(VIDEOINFOHEADER));
                            info.VideoSize = new Size(vih.bmiHeader.biWidth, vih.bmiHeader.biHeight);
                        }

                        // コレクションに追加.
                        result.Add(info);
                    }
                    finally
                    {
                        if (mt != null)
                        {
                            Axi.FreeMediaType(ref mt);
                        }
                    }
                }
            }
            finally
            {
                if (dataptr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(dataptr);
                }
            }

            return(result);
        }