コード例 #1
0
ファイル: Capture.cs プロジェクト: ewin66/DirectShow.NET
        private IBaseFilter ConfigAsf(ICaptureGraphBuilder2 capGraph, string szOutputFileName)
        {
            IFileSinkFilter pTmpSink  = null;
            IBaseFilter     asfWriter = null;

            int hr = capGraph.SetOutputFileName(MediaSubType.Asf, szOutputFileName, out asfWriter, out pTmpSink);

            Marshal.ThrowExceptionForHR(hr);

            try
            {
                IConfigAsfWriter lConfig = asfWriter as IConfigAsfWriter;

                // Windows Media Video 8 for Dial-up Modem (No audio, 56 Kbps)
                // READ THE README for info about using guids
                Guid cat = new Guid(0x6E2A6955, 0x81DF, 0x4943, 0xBA, 0x50, 0x68, 0xA9, 0x86, 0xA7, 0x08, 0xF6);

                hr = lConfig.ConfigureFilterUsingProfileGuid(cat);
                Marshal.ThrowExceptionForHR(hr);
            }
            finally
            {
                Marshal.ReleaseComObject(pTmpSink);
            }

            return(asfWriter);
        }
コード例 #2
0
        private void Configure()
        {
            int hr;

            m_FilterGraph = (IFilterGraph2) new FilterGraph();

            m_asfw = (IConfigAsfWriter) new WMAsfWriter();
            hr     = m_FilterGraph.AddFilter((IBaseFilter)m_asfw, "asdf");
            DsError.ThrowExceptionForHR(hr);
        }
コード例 #3
0
        /// <summary>
        /// 初始化图表
        /// </summary>
        public bool InitGraph(string sViewPath)
        {
            if (!VerStarPreview())
            {
                MessageBox.Show("请先开始预览!");
                return(false);
            }
            mediaControl.Stop();
            CreateGraph(_Resolution, _Frames);
            int hr;

            if (sVideoType == "wmv")
            {
                hr = captureGraphBuilder.SetOutputFileName(MediaSubType.Asf, sViewPath, out mux, out sink);
                Marshal.ThrowExceptionForHR(hr);
                try
                {
                    IConfigAsfWriter lConfig = mux as IConfigAsfWriter;

                    // Windows Media Video (audio, 700 Kbps)
                    // READ THE README for info about using guids
                    Guid cat = new Guid("ec298949-639b-45e2-96fd-4ab32d5919c2");
                    hr = lConfig.ConfigureFilterUsingProfileGuid(cat);
                    Marshal.ThrowExceptionForHR(hr);
                }
                finally
                {
                    Marshal.ReleaseComObject(sink);
                }
            }
            else if (sVideoType == "avi")
            {
                hr = captureGraphBuilder.SetOutputFileName(MediaSubType.Avi, sViewPath, out mux, out sink);
                DsError.ThrowExceptionForHR(hr);
            }
            //将设备和压缩器连接到mux,以呈现图形的捕获部分
            hr = captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Interleaved, theDevice, theDeviceCompressor, mux);
            //DsError.ThrowExceptionForHR(hr);
            if (hr < 0)
            {
                hr = captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Video, theDevice, theDeviceCompressor, mux);
                if (hr < 0)
                {
                    DsError.ThrowExceptionForHR(hr);
                }
            }

            //将音频添加进去
            hr = captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Audio, theAudio, theAudioCompressor, mux);
            DsError.ThrowExceptionForHR(hr);

            Marshal.ReleaseComObject(mux);
            Marshal.ReleaseComObject(sink);
            return(true);
        }
コード例 #4
0
        /// <summary>
        /// Update Asf audio/video item information
        /// </summary>
        /// <param name="asfWriter"></param>
        /// <param name="asfItem"></param>
        /// <returns></returns>
        public bool UpdateAsfAVFormat(IBaseFilter asfWriter, int asfItem)
        {
            if (asfWriter != null)
            {
                IConfigAsfWriter lConfig = asfWriter as IConfigAsfWriter;
                int hr = 0;

                // Set Windows Media Audio/Video format first
                if (asfItem >= 0)
                {
                    // Get Guid for this item
                    Guid guid = GetAsfItemGuid(asfItem);

                    if (guid != Guid.Empty)
                    {
                        // Obsolete interface ???
                        hr = lConfig.ConfigureFilterUsingProfileGuid(guid);
                        if (hr < 0)
                        {
                            MessageBox.Show("Problems with updating Windows Media audio/video format information via Guid.");
                            return(false);
                        }
                        else
                        {
                            this.CurrentAsfItem = asfItem;
                        }
                    }
                    else
                    if (this[asfItem].Filename.Length > 0)
                    {
                        if (!this.ConfigProfileFromFile(asfWriter, this[asfItem].Filename))
                        {
                            MessageBox.Show("Problems with updating Windows Media audio/video format information via prx file.");
                        }
                        else
                        {
                            this.CurrentAsfItem = asfItem;
                        }
                    }
                }

                // Set other (more general) settings, if needed

                // Set index
                hr = lConfig.SetIndexMode(this.UseIndex);
                if (hr < 0)
                {
                    MessageBox.Show("Problems with updating Windows Media index information.");
                }
            }
            return(true);
        }
コード例 #5
0
        // End of NEW

        /// <summary>
        /// Configure profile from file to Asf file writer
        /// </summary>
        /// <param name="asfWriter"></param>
        /// <param name="filename"></param>
        /// <returns></returns>
        public bool ConfigProfileFromFile(IBaseFilter asfWriter, string filename)
        {
            int hr;

            //string profilePath = "test.prx";
            // Set the profile to be used for conversion
            if ((filename != null) && (File.Exists(filename)))
            {
                // Load the profile XML contents
                string profileData;
                using (StreamReader reader = new StreamReader(File.OpenRead(filename)))
                {
                    profileData = reader.ReadToEnd();
                }

                // Create an appropriate IWMProfile from the data
                // Open the profile manager
                IWMProfileManager profileManager;
                IWMProfile        wmProfile = null;
                hr = WMLib.WMCreateProfileManager(out profileManager);
                if (hr >= 0)
                {
                    // error message: The profile is invalid (0xC00D0BC6)
                    // E.g. no <prx> tags
                    hr = profileManager.LoadProfileByData(profileData, out wmProfile);
                }

                if (profileManager != null)
                {
                    Marshal.ReleaseComObject(profileManager);
                    profileManager = null;
                }

                // Config only if there is a profile retrieved
                if (hr >= 0)
                {
                    // Set the profile on the writer
                    IConfigAsfWriter configWriter = (IConfigAsfWriter)asfWriter;
                    hr = configWriter.ConfigureFilterUsingProfile(wmProfile);
                    if (hr >= 0)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
コード例 #6
0
        private void InitAsfWriter(out IBaseFilter asfWriter, bool shittyQuality = false)
        {
            int hr;

            asfWriter = (IBaseFilter) new WMAsfWriter();

            hr = m_FilterGraph.AddFilter(asfWriter, "ASF Writer");
            Marshal.ThrowExceptionForHR(hr);

            if (shittyQuality)
            {
                return;
            }
            // Create an appropriate IWMProfile from the data
            // Open the profile manager
            IWMProfileManager profileManager;
            IWMProfile        wmProfile = null;

            WMUtils.WMCreateProfileManager(out profileManager);

            // error message: The profile is invalid (0xC00D0BC6)
            // E.g. no <prx> tags
            string profile = System.Text.Encoding.ASCII.GetString(Convert.FromBase64String(customGoodProfile));

            profileManager.LoadProfileByData(profile, out wmProfile);

            if (profileManager != null)
            {
                Marshal.ReleaseComObject(profileManager);
                profileManager = null;
            }

            // Config only if there is a profile retrieved
            // Set the profile on the writer
            IConfigAsfWriter configWriter = (IConfigAsfWriter)asfWriter;

            configWriter.ConfigureFilterUsingProfile(wmProfile);
        }
コード例 #7
0
        private bool AddWmAsfWriter(string fileName, Quality quality, Standard standard)
        {
            //add asf file writer
            IPin pinOut0, pinOut1;
            IPin pinIn0, pinIn1;

            Log.Info("DVRMS2WMV: add WM ASF Writer to graph");
            string monikerAsfWriter =
                @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{7C23220E-55BB-11D3-8B16-00C04FB6BD3D}";

            fileWriterbase = Marshal.BindToMoniker(monikerAsfWriter) as IBaseFilter;
            if (fileWriterbase == null)
            {
                Log.Error("DVRMS2WMV:FAILED:Unable to create ASF WM Writer");
                Cleanup();
                return(false);
            }

            int hr = graphBuilder.AddFilter(fileWriterbase, "WM ASF Writer");

            if (hr != 0)
            {
                Log.Error("DVRMS2WMV:FAILED:Add ASF WM Writer to filtergraph :0x{0:X}", hr);
                Cleanup();
                return(false);
            }
            IFileSinkFilter2 fileWriterFilter = fileWriterbase as IFileSinkFilter2;

            if (fileWriterFilter == null)
            {
                Log.Error("DVR2XVID:FAILED:Add unable to get IFileSinkFilter for filewriter");
                Cleanup();
                return(false);
            }
            hr = fileWriterFilter.SetFileName(fileName, null);
            hr = fileWriterFilter.SetMode(AMFileSinkFlags.OverWrite);
            Log.Info("DVRMS2WMV: connect audio/video codecs outputs -> ASF WM Writer");
            //connect output #0 of videocodec->asf writer pin 1
            //connect output #0 of audiocodec->asf writer pin 0
            pinOut0 = DsFindPin.ByDirection((IBaseFilter)Mpeg2AudioCodec, PinDirection.Output, 0);
            pinOut1 = DsFindPin.ByDirection((IBaseFilter)Mpeg2VideoCodec, PinDirection.Output, 0);
            if (pinOut0 == null || pinOut1 == null)
            {
                Log.Error("DVRMS2WMV:FAILED:unable to get outpins of video codec");
                Cleanup();
                return(false);
            }
            pinIn0 = DsFindPin.ByDirection(fileWriterbase, PinDirection.Input, 0);
            if (pinIn0 == null)
            {
                Log.Error("DVRMS2WMV:FAILED:unable to get pins of asf wm writer");
                Cleanup();
                return(false);
            }
            hr = graphBuilder.Connect(pinOut0, pinIn0);
            if (hr != 0)
            {
                Log.Error("DVRMS2WMV:FAILED:unable to connect audio pins :0x{0:X}", hr);
                Cleanup();
                return(false);
            }
            pinIn1 = DsFindPin.ByDirection(fileWriterbase, PinDirection.Input, 1);
            if (pinIn1 == null)
            {
                Log.Error("DVRMS2WMV:FAILED:unable to get pins of asf wm writer");
                Cleanup();
                return(false);
            }
            hr = graphBuilder.Connect(pinOut1, pinIn1);
            if (hr != 0)
            {
                Log.Error("DVRMS2WMV:FAILED:unable to connect video pins :0x{0:X}", hr);
                Cleanup();
                return(false);
            }

            IConfigAsfWriter   config          = fileWriterbase as IConfigAsfWriter;
            IWMProfileManager  profileManager  = null;
            IWMProfileManager2 profileManager2 = null;
            IWMProfile         profile         = null;

            hr = WMLib.WMCreateProfileManager(out profileManager);
            string strprofileType = "";

            switch (quality)
            {
            case Quality.HiDef:
                //hr = WMLib.WMCreateProfileManager(out profileManager);
                if (standard == Standard.Film)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPHiDef-FILM.prx");
                }
                if (standard == Standard.NTSC)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPHiDef-NTSC.prx");
                }
                if (standard == Standard.PAL)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPHiDef-PAL.prx");
                }
                Log.Info("DVRMS2WMV: set WMV HiDef quality profile {0}", strprofileType);
                break;

            case Quality.VeryHigh:
                if (standard == Standard.Film)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPVeryHigh-FILM.prx");
                }
                if (standard == Standard.NTSC)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPVeryHigh-NTSC.prx");
                }
                if (standard == Standard.PAL)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPVeryHigh-PAL.prx");
                }
                Log.Info("DVRMS2WMV: set WMV Very High quality profile {0}", strprofileType);
                break;

            case Quality.High:
                if (standard == Standard.Film)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPHigh-FILM.prx");
                }
                if (standard == Standard.NTSC)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPHigh-NTSC.prx");
                }
                if (standard == Standard.PAL)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPHigh-PAL.prx");
                }
                Log.Info("DVRMS2WMV: set WMV High quality profile {0}", strprofileType);
                break;

            case Quality.Medium:
                if (standard == Standard.Film)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPMedium-FILM.prx");
                }
                if (standard == Standard.NTSC)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPMedium-NTSC.prx");
                }
                if (standard == Standard.PAL)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPMedium-PAL.prx");
                }
                Log.Info("DVRMS2WMV: set WMV Medium quality profile {0}", strprofileType);
                break;

            case Quality.Low:
                if (standard == Standard.Film)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPLow-FILM.prx");
                }
                if (standard == Standard.NTSC)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPLow-NTSC.prx");
                }
                if (standard == Standard.PAL)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPLow-PAL.prx");
                }
                Log.Info("DVRMS2WMV: set WMV Low quality profile {0}", strprofileType);
                break;

            case Quality.Portable:
                if (standard == Standard.Film)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPPortable-FILM.prx");
                }
                if (standard == Standard.NTSC)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPPortable-NTSC.prx");
                }
                if (standard == Standard.PAL)
                {
                    strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPPortable-PAL.prx");
                }
                Log.Info("DVRMS2WMV: set WMV Portable quality profile {0}", strprofileType);
                break;

            case Quality.Custom:
                //load custom profile
                string customBitrate = "";
                //Adjust the parameters to suit the custom settings the user has selected.
                switch (bitrate)
                {
                case 0:
                    customBitrate = "100Kbs";
                    break;

                case 1:
                    customBitrate = "256Kbs";
                    break;

                case 2:
                    customBitrate = "384Kbs";
                    break;

                case 3:
                    customBitrate = "768Kbs";
                    break;

                case 4:
                    customBitrate = "1536Kbs";
                    break;

                case 5:
                    customBitrate = "3072Kbs";
                    break;

                case 6:
                    customBitrate = "5376Kbs";
                    break;
                }
                Log.Info("DVRMS2WMV: custom bitrate = {0}", customBitrate);
                //TODO: get fps values & frame size
                //TODO: adjust settings required
                //Call the SetCutomPorfile method to load the custom profile, adjust it's params from user settings & then save it.
                //SetCutomProfile(videoBitrate, audioBitrate, videoHeight, videoWidth, videoFps); //based on user inputs
                //We then reload it after as per other quality settings / profiles.
                strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPCustom.prx");
                Log.Info("DVRMS2WMV: set WMV Custom quality profile {0}", strprofileType);
                break;
            }
            //Loads profile from the above quality selection.
            using (StreamReader prx = new StreamReader(strprofileType))
            {
                String profileContents = prx.ReadToEnd();
                profileManager2 = profileManager as IWMProfileManager2;

                hr = profileManager2.LoadProfileByData(profileContents, out profile);
                if (hr != 0)
                {
                    Log.Info("DVRMS2WMV: get WMV profile - FAILED! {0}", hr);
                    Cleanup();
                    return(false);
                }
            }


            Log.Info("DVRMS2WMV: load profile - SUCCESS!");
            //configures the WM ASF Writer to the chosen profile
            hr = config.ConfigureFilterUsingProfile(profile);
            if (hr != 0)
            {
                Log.Info("DVRMS2WMV: configure profile - FAILED! {0}", hr);
                Cleanup();
                return(false);
            }
            Log.Info("DVRMS2WMV: configure profile - SUCCESS!");
            //TODO: Add DB recording information into WMV.

            //Release resorces
            if (profile != null)
            {
                Marshal.ReleaseComObject(profile);
                profile = null;
            }
            if (profileManager != null)
            {
                Marshal.ReleaseComObject(profileManager);
                profileManager = null;
            }
            return(true);
        }
コード例 #8
0
        /// <summary>
        /// WMV 形式ファイル保存用: ビデオのフレームサイズを設定します。
        /// </summary>
        /// <param name="config">ASF Writer から取得したインターフェース</param>
        /// <param name="size">設定値</param>
        /// <remarks>
        ///		第一引数の <c>config</c> は下記のように取得してください。<br/>
        ///		<example lang="c#">
        ///			var filetype = new Guid(GUID.MEDIASUBTYPE_Asf);
        ///			builder.SetOutputFileName(new IntPtr(&amp;filetype), filename, ref videoRenderer, ref fileSink);
        ///			var config = (IConfigAsfWriter)videoRenderer;
        ///		</example>
        ///		<br/>
        ///		詳細は下記に記載されています。(但し、言語は C++ です。) <br/>
        ///		<br/>
        ///		<list type="bullet">
        ///			<item>
        ///				Capturing Video to a Windows Media File <br/>
        ///				https://msdn.microsoft.com/en-us/library/windows/desktop/dd318630(v=vs.85).aspx
        ///			</item>
        ///			<item>
        ///				Creating ASF Files in DirectShow <br/>
        ///				https://msdn.microsoft.com/en-us/library/windows/desktop/dd375008(v=vs.85).aspx
        ///				<list type="bullet">
        ///				<item>
        ///					Configuring the ASF Writer <br/>
        ///					https://msdn.microsoft.com/en-us/library/windows/desktop/dd387911(v=vs.85).aspx
        ///				</item>
        ///				</list>
        ///			</item>
        ///			<item>
        ///				Using Windows Media in DirectShow <br/>
        ///				https://msdn.microsoft.com/en-us/library/windows/desktop/dd407300(v=vs.85).aspx
        ///				<list type="bullet">
        ///				<item>
        ///					WM ASF Writer Filter <br/>
        ///					https://msdn.microsoft.com/en-us/library/windows/desktop/dd390985(v=vs.85).aspx
        ///				</item>
        ///				</list>
        ///			</item>
        ///		</list>
        ///		<br/>
        ///		しかし、上記の説明だけでは解決できないので、下記も参考にしています。<br/>
        ///		Social <br/>
        ///		https://social.msdn.microsoft.com/Forums/sqlserver/en-US/962d4370-5fde-4d23-83bc-b8f6191b375e/asf-writer-creates-a-file-that-appears-not-to-match-the-encoding-profile-settings?forum=windowsdirectshowdevelopment <br/>
        ///		https://social.msdn.microsoft.com/forums/windowsdesktop/en-us/fb0a6151-d916-422a-966b-ee1fb164df5f/asf-profile-configurations-fails <br/>
        /// </remarks>
        public static void SetVideoFrameSize(IConfigAsfWriter config, Size size)
        {
            try
            {
                HRESULT hr;

                // 現在のプロファイルを取得します.
                IWMProfile profile;
                hr = (HRESULT)config.GetCurrentProfile(out profile);
                if (hr < HRESULT.S_OK)
                {
                    throw new CxDSException(hr);
                }

                // ストリームの個数を取得します.
                uint stream_num;
                hr = (HRESULT)profile.GetStreamCount(out stream_num);
                if (hr < HRESULT.S_OK)
                {
                    throw new CxDSException(hr);
                }

                // 映像入力のストリームを探索してフレームサイズを設定します.
                for (uint index = 0; index < stream_num; index++)
                {
                    // ストリームを取得します.
                    IWMStreamConfig stream_config;
                    hr = (HRESULT)profile.GetStream(index, out stream_config);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }

                    // ストリームのメディアタイプを確認します.
                    Guid stream_type;
                    hr = (HRESULT)stream_config.GetStreamType(out stream_type);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }

                    // 映像以外は無視します.
                    if (stream_type != new Guid(GUID.MEDIATYPE_Video))
                    {
                        continue;
                    }

                    // メディアタイプ情報を格納するために必要なサイズ (bytes) を取得します.
                    var props  = (IWMMediaProps)stream_config;
                    int cbType = 0;
                    hr = (HRESULT)props.GetMediaType(IntPtr.Zero, ref cbType);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }

                    // メディアタイプ情報を格納する領域を確保します.
                    var pwmt = Marshal.AllocHGlobal(cbType);
                    if (pwmt != IntPtr.Zero)
                    {
                        try
                        {
                            // メディアタイプ情報を取得します.
                            hr = (HRESULT)props.GetMediaType(pwmt, ref cbType);
                            if (hr < HRESULT.S_OK)
                            {
                                throw new CxDSException(hr);
                            }

                            // フレームサイズを指定された値に書き替えます.
                            unsafe
                            {
                                var wmt = (WM_MEDIA_TYPE *)pwmt;
                                var vih = (VIDEOINFOHEADER *)wmt->pbFormat;
                                vih->bmiHeader.biWidth  = size.Width;                                           // 幅.
                                vih->bmiHeader.biHeight = size.Height;                                          // 高さ.
                            }

                            // メディアタイプを設定します.
                            hr = (HRESULT)props.SetMediaType(pwmt);
                            if (hr < HRESULT.S_OK)
                            {
                                throw new CxDSException(hr);
                            }
                        }
                        finally
                        {
                            Marshal.FreeHGlobal(pwmt);
                        }
                    }

                    // ストリームを再構成します.
                    hr = (HRESULT)profile.ReconfigStream(stream_config);
                    if (hr < HRESULT.S_OK)
                    {
                        throw new CxDSException(hr);
                    }
                }

                // プロファイルを再構成します.
                hr = (HRESULT)config.ConfigureFilterUsingProfile(profile);
                if (hr < HRESULT.S_OK)
                {
                    throw new CxDSException(hr);
                }
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
        }