/// <summary> /// The <see cref="Control.Click"/> event handler for the /// <see cref="Button"/> <see cref="btnVideoDeviceProperties"/>. /// Calls a <see cref="Webcam.ShowVideoDeviceConfigureDialog()"/>. /// </summary> /// <param name="sender">Source of the event.</param> /// <param name="e">An empty <see cref="EventArgs"/>.</param> private void btnVideoDeviceProperties_Click(object sender, EventArgs e) { if (this.dxCapture.VideoDeviceFilter != null) { DirectShowUtils.DisplayPropertyPage(this.Handle, this.dxCapture.VideoDeviceFilter); } }
/// <summary> /// The <see cref="Control.Click"/> event handler for the /// <see cref="Button"/> <see cref="btnAudioCompressorProperties"/>. /// Calls a <see cref="Webcam.ShowAudioCompressorConfigureDialog()"/>. /// </summary> /// <param name="sender">Source of the event.</param> /// <param name="e">An empty <see cref="EventArgs"/>.</param> private void btnAudioCompressorProperties_Click(object sender, EventArgs e) { if (this.dxCapture.AudioCompressorFilter != null) { DirectShowUtils.DisplayPropertyPage(this.Handle, this.dxCapture.AudioCompressorFilter); } }
/// <summary> /// This method displays the property pages for the current audio compressor. /// </summary> public void ShowAudioCompressorConfigureDialog() { if (this.dxCapture == null) { return; } if (this.dxCapture.AudioCompressorFilter != null) { DirectShowUtils.DisplayPropertyPage(this.Handle, this.dxCapture.AudioCompressorFilter); } }
/// <summary> /// This method displays the property pages for the current video device. /// </summary> public void ShowVideoDeviceConfigureDialog() { if (this.dxCapture == null) { return; } if (this.dxCapture.VideoDeviceFilter != null) { DirectShowUtils.DisplayPropertyPage(this.Handle, this.dxCapture.VideoDeviceFilter); } }
/////////////////////////////////////////////////////////////////////////////// // Public methods // /////////////////////////////////////////////////////////////////////////////// #region PUBLICMETHODS #endregion //PUBLICMETHODS /////////////////////////////////////////////////////////////////////////////// // Inherited methods // /////////////////////////////////////////////////////////////////////////////// #region OVERRIDES #endregion //OVERRIDES /////////////////////////////////////////////////////////////////////////////// // Eventhandler // /////////////////////////////////////////////////////////////////////////////// #region EVENTS /////////////////////////////////////////////////////////////////////////////// // Eventhandler for UI, Menu, Buttons, Toolbars etc. // /////////////////////////////////////////////////////////////////////////////// #region WINDOWSEVENTHANDLER /// <summary> /// The <see cref="Control.Click"/> event handler for the /// <see cref="Button"/> <see cref="btnEncoderProperties"/>. /// Shows the property pages of the selected filter. /// </summary> /// <param name="sender">Source of the event.</param> /// <param name="e">An empty <see cref="EventArgs"/></param> private void btnEncoderProperties_Click(object sender, EventArgs e) { // Create the filter for the selected video compressor IBaseFilter compressorFilter = DirectShowUtils.CreateFilter( FilterCategory.VideoCompressorCategory, this.cbbEncoderFilter.Text); if (compressorFilter != null) { DirectShowUtils.DisplayPropertyPage(this.Handle, compressorFilter); Marshal.ReleaseComObject(compressorFilter); } }
/// <summary> build the capture graph for grabber. </summary> private void SetupGraph(string destFilename, string encoderName) { int hr; // Get the graphbuilder object captureGraphBuilder = new DirectShowLib.CaptureGraphBuilder2() as DirectShowLib.ICaptureGraphBuilder2; IFilterGraph2 filterGraph = new DirectShowLib.FilterGraph() as DirectShowLib.IFilterGraph2; mediaCtrl = filterGraph as DirectShowLib.IMediaControl; IMediaFilter mediaFilt = filterGraph as IMediaFilter; mediaEvent = filterGraph as IMediaEvent; captureGraphBuilder.SetFiltergraph(filterGraph); IBaseFilter aviMux; IFileSinkFilter fileSink = null; hr = captureGraphBuilder.SetOutputFileName(MediaSubType.Avi, destFilename, out aviMux, out fileSink); DsError.ThrowExceptionForHR(hr); DirectShowLib.IBaseFilter compressor = DirectShowUtils.GetVideoCompressor(encoderName); if (compressor == null) { throw new InvalidCodecException(encoderName); } hr = filterGraph.AddFilter(compressor, "compressor"); DsError.ThrowExceptionForHR(hr); // Our data source IBaseFilter source = (IBaseFilter) new GenericSampleSourceFilter(); // Get the pin from the filter so we can configure it IPin ipin = DsFindPin.ByDirection(source, PinDirection.Output, 0); try { // Configure the pin using the provided BitmapInfo ConfigurePusher((IGenericSampleConfig)ipin); } finally { Marshal.ReleaseComObject(ipin); } // Add the filter to the graph hr = filterGraph.AddFilter(source, "GenericSampleSourceFilter"); Marshal.ThrowExceptionForHR(hr); hr = filterGraph.AddFilter(source, "source"); DsError.ThrowExceptionForHR(hr); hr = captureGraphBuilder.RenderStream(null, null, source, compressor, aviMux); DsError.ThrowExceptionForHR(hr); IMediaPosition mediaPos = filterGraph as IMediaPosition; hr = mediaCtrl.Run(); DsError.ThrowExceptionForHR(hr); }
/////////////////////////////////////////////////////////////////////////////// // Construction and Initializing methods // /////////////////////////////////////////////////////////////////////////////// #region CONSTRUCTION /// <summary> /// Initializes a new instance of the DSRecordWithDMO class. /// </summary> /// <param name="newImageHandler">An <see cref="ImageFromVectorGraphics"/> /// with the callback.</param> /// <param name="newVideoExportProperties">A <see cref="VideoExportProperties"/> with /// the video export properties.</param> /// <param name="newPreviewWindow">A <see cref="Control"/> with /// the preview panel.</param> public DSRecordWithDMO( ImageFromVectorGraphics newImageHandler, VideoExportProperties newVideoExportProperties, Control newPreviewWindow) { try { // set the image provider this.imageHandler = newImageHandler; // set the video properties this.videoExportProperties = newVideoExportProperties; if (this.videoExportProperties.OutputVideoProperties.VideoCompressor != string.Empty) { // Create the filter for the selected video compressor this.videoCompressor = DirectShowUtils.CreateFilter( FilterCategory.VideoCompressorCategory, this.videoExportProperties.OutputVideoProperties.VideoCompressor); } if (this.videoExportProperties.OutputVideoProperties.AudioCompressor != string.Empty) { // Create the filter for the selected video compressor this.audioCompressor = DirectShowUtils.CreateFilter( FilterCategory.AudioCompressorCategory, this.videoExportProperties.OutputVideoProperties.AudioCompressor); } // Set up preview window this.previewWindow = newPreviewWindow; // Set up the graph if (!this.SetupGraph()) { throw new OperationCanceledException("The DirectShow graph could not be created," + " try to use another video or audio compressor."); } } catch { this.Dispose(); throw; } }
/////////////////////////////////////////////////////////////////////////////// // Methods and Eventhandling for Background tasks // /////////////////////////////////////////////////////////////////////////////// #region THREAD #endregion //THREAD /////////////////////////////////////////////////////////////////////////////// // Methods for doing main class job // /////////////////////////////////////////////////////////////////////////////// #region PRIVATEMETHODS /// <summary> /// Create a new filter graph and add filters (devices, compressors, /// misc), but leave the filters unconnected. Call renderGraph() /// to connect the filters. /// </summary> /// <returns>True if successful created the graph.</returns> protected bool CreateGraph() { int hr; try { // Garbage collect, ensure that previous filters are released GC.Collect(); // Get the graphbuilder object this.graphBuilder = new FilterGraph() as IFilterGraph2; // Get a ICaptureGraphBuilder2 to help build the graph this.captureGraphBuilder = new CaptureGraphBuilder2() as ICaptureGraphBuilder2; // Link the CaptureGraphBuilder to the filter graph hr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder); DsError.ThrowExceptionForHR(hr); #if DEBUG this.rotCookie = new DsROTEntry(this.graphBuilder); #endif // Add the Video input device to the graph //// Add the video device //IBaseFilter videoSourceFilter; //hr = this.graphBuilder.AddSourceFilterForMoniker(this.captureDeviceProperties.VideoInputDevice.DirectshowDevice.Mon, null, "Video Source", out videoSourceFilter); //DsError.ThrowExceptionForHR(hr); //this.VideoDeviceFilter = videoSourceFilter; this.VideoDeviceFilter = DirectShowUtils.CreateFilter( FilterCategory.VideoInputDevice, this.captureDeviceProperties.VideoInputDevice.Name); if (this.VideoDeviceFilter != null) { hr = graphBuilder.AddFilter(this.VideoDeviceFilter, "Video Source"); DsError.ThrowExceptionForHR(hr); } // Add the Audio input device to the graph this.AudioDeviceFilter = DirectShowUtils.CreateFilter( FilterCategory.AudioInputDevice, this.captureDeviceProperties.AudioInputDevice); if (this.AudioDeviceFilter != null) { hr = graphBuilder.AddFilter(this.AudioDeviceFilter, "Audio Source"); DsError.ThrowExceptionForHR(hr); } // Retrieve the stream control interface for the video device // FindInterface will also add any required filters // (WDM devices in particular may need additional // upstream filters to function). DsGuid cat; DsGuid med; // Try looking for an interleaved media type object o; cat = PinCategory.Capture; med = MediaType.Interleaved; Guid iid = typeof(IAMStreamConfig).GUID; hr = captureGraphBuilder.FindInterface(cat, med, this.VideoDeviceFilter, iid, out o); if (hr != 0) { // If not found, try looking for a video media type med = MediaType.Video; hr = captureGraphBuilder.FindInterface( cat, med, this.VideoDeviceFilter, iid, out o); if (hr != 0) { o = null; } } videoStreamConfig = o as IAMStreamConfig; this.SetConfigParms( videoStreamConfig, this.captureDeviceProperties.FrameRate, this.captureDeviceProperties.VideoSize.Width, this.captureDeviceProperties.VideoSize.Height); // Render capture stream (only if necessary) if ((this.captureDeviceProperties.CaptureMode & CaptureMode.VideoCapture) == CaptureMode.VideoCapture || (this.captureDeviceProperties.CaptureMode & CaptureMode.AudioCapture) == CaptureMode.AudioCapture) { // Get the video compressor and add it to the filter graph // Create the filter for the selected video compressor this.VideoCompressorFilter = DirectShowUtils.CreateFilter( FilterCategory.VideoCompressorCategory, this.captureDeviceProperties.VideoCompressor); if (this.VideoCompressorFilter != null) { hr = this.graphBuilder.AddFilter(this.VideoCompressorFilter, "Video Compressor"); DsError.ThrowExceptionForHR(hr); } // Get the video compressor and add it to the filter graph // Create the filter for the selected video compressor this.AudioCompressorFilter = DirectShowUtils.CreateFilter( FilterCategory.AudioCompressorCategory, this.captureDeviceProperties.AudioCompressor); if (this.AudioCompressorFilter != null) { hr = this.graphBuilder.AddFilter(this.AudioCompressorFilter, "Audio Compressor"); DsError.ThrowExceptionForHR(hr); } // Ensure required properties set if (this.captureDeviceProperties.Filename == null || this.captureDeviceProperties.Filename == string.Empty) { throw new ArgumentException("The Filename property has not been set to a file.\n"); } // Render the file writer portion of graph (mux -> file) hr = this.captureGraphBuilder.SetOutputFileName( MediaSubType.Avi, this.captureDeviceProperties.Filename, out this.muxFilter, out this.fileWriterFilter); DsError.ThrowExceptionForHR(hr); // Render video (video -> mux) if (this.VideoDeviceFilter != null && ((this.captureDeviceProperties.CaptureMode & CaptureMode.VideoCapture) == CaptureMode.VideoCapture)) { // Try interleaved first, because if the device supports it, // it's the only way to get audio as well as video cat = PinCategory.Capture; med = MediaType.Interleaved; hr = captureGraphBuilder.RenderStream( cat, med, this.VideoDeviceFilter, this.VideoCompressorFilter, muxFilter); // If interleaved fails try video if (hr < 0) { med = MediaType.Video; hr = captureGraphBuilder.RenderStream( cat, med, this.VideoDeviceFilter, this.VideoCompressorFilter, muxFilter); if (hr == -2147220969) { throw new ArgumentException("Video device is already in use"); } DsError.ThrowExceptionForHR(hr); } hr = captureGraphBuilder.RenderStream( null, null, this.VideoDeviceFilter, this.VideoCompressorFilter, muxFilter); } // Render audio (audio -> mux) if (this.AudioDeviceFilter != null && ((this.captureDeviceProperties.CaptureMode & CaptureMode.AudioCapture) == CaptureMode.AudioCapture)) { cat = PinCategory.Capture; med = MediaType.Audio; hr = captureGraphBuilder.RenderStream( cat, med, this.AudioDeviceFilter, this.AudioCompressorFilter, muxFilter); DsError.ThrowExceptionForHR(hr); } } // Render preview stream (only if necessary) if ((this.captureDeviceProperties.CaptureMode & CaptureMode.VideoPreview) == CaptureMode.VideoPreview || (this.captureDeviceProperties.CaptureMode & CaptureMode.AudioPrehear) == CaptureMode.AudioPrehear) { if (this.VideoDeviceFilter != null && ((this.captureDeviceProperties.CaptureMode & CaptureMode.VideoPreview) == CaptureMode.VideoPreview)) { // Render preview (video -> renderer) hr = captureGraphBuilder.RenderStream( PinCategory.Preview, MediaType.Video, this.VideoDeviceFilter, null, null); string error = DsError.GetErrorText(hr); DsError.ThrowExceptionForHR(hr); } if (this.AudioDeviceFilter != null && ((this.captureDeviceProperties.CaptureMode & CaptureMode.AudioPrehear) == CaptureMode.AudioPrehear)) { // Render audio (audio -> renderer) hr = captureGraphBuilder.RenderStream( PinCategory.Preview, MediaType.Audio, this.AudioDeviceFilter, null, null); string error = DsError.GetErrorText(hr); DsError.ThrowExceptionForHR(hr); } } // Retrieve RetreiveGraphReferenceClock(); // Retreive the media control interface (for starting/stopping graph) this.mediaControl = (IMediaControl)this.graphBuilder; // Get the IVideoWindow interface this.videoWindow = (IVideoWindow)this.graphBuilder; } catch (Exception ex) { MessageBox.Show("Error in creating usercamera graph: " + ex.ToString()); return(false); } this.HasValidGraph = true; return(true); }
/////////////////////////////////////////////////////////////////////////////// // Inherited methods // /////////////////////////////////////////////////////////////////////////////// #region OVERRIDES #endregion //OVERRIDES /////////////////////////////////////////////////////////////////////////////// // Eventhandler // /////////////////////////////////////////////////////////////////////////////// #region EVENTS /////////////////////////////////////////////////////////////////////////////// // Eventhandler for UI, Menu, Buttons, Toolbars etc. // /////////////////////////////////////////////////////////////////////////////// #region WINDOWSEVENTHANDLER #endregion //WINDOWSEVENTHANDLER /////////////////////////////////////////////////////////////////////////////// // Eventhandler for Custom Defined Events // /////////////////////////////////////////////////////////////////////////////// #region CUSTOMEVENTHANDLER #endregion //CUSTOMEVENTHANDLER #endregion //EVENTS /////////////////////////////////////////////////////////////////////////////// // Methods and Eventhandling for Background tasks // /////////////////////////////////////////////////////////////////////////////// #region BACKGROUNDWORKER #endregion //BACKGROUNDWORKER /////////////////////////////////////////////////////////////////////////////// // Methods for doing main class job // /////////////////////////////////////////////////////////////////////////////// #region PRIVATEMETHODS /// <summary> /// Create a new filter graph and add filters (devices, compressors, /// misc), but leave the filters unconnected. Call renderGraph() /// to connect the filters. /// </summary> /// <returns>True if successful created the graph.</returns> protected bool createGraph() { int hr; try { // Garbage collect, ensure that previous filters are released GC.Collect(); // Get the graphbuilder object this.graphBuilder = new FilterGraph() as IFilterGraph2; // Get a ICaptureGraphBuilder2 to help build the graph this.captureGraphBuilder = new CaptureGraphBuilder2() as ICaptureGraphBuilder2; // Link the CaptureGraphBuilder to the filter graph hr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder); DsError.ThrowExceptionForHR(hr); #if DEBUG this.rotCookie = new DsROTEntry(this.graphBuilder); #endif // this.screenCaptureFilter = (IBaseFilter)new OgamaScreenCaptureFilter(); // Get the ogama screen capture device and add it to the filter graph this.screenCaptureFilter = DirectShowUtils.CreateFilter(FilterCategory.VideoInputDevice, "OgamaCapture"); hr = this.graphBuilder.AddFilter(this.screenCaptureFilter, "OgamaCapture"); DsError.ThrowExceptionForHR(hr); // Query the interface for the screen capture Filter var ogamaFilter = this.screenCaptureFilter as IOgamaScreenCapture; hr = ogamaFilter.set_Monitor(this.monitorIndex); DsError.ThrowExceptionForHR(hr); hr = ogamaFilter.set_Framerate(this.frameRate); DsError.ThrowExceptionForHR(hr); //// Get the IAMStreamConfig from the filter so we can configure it //var videoStreamConfig = this.screenCaptureFilter as IAMStreamConfig; var resolution = PresentationScreen.GetPresentationResolution(); //hr = videoStreamConfig.SetFormat(this.CreateVideoMediaType(24, resolution.Width, resolution.Height)); //DsError.ThrowExceptionForHR(hr); this.smartTeeFilter = new SmartTee() as IBaseFilter; hr = this.graphBuilder.AddFilter(this.smartTeeFilter, "Smart Tee"); DsError.ThrowExceptionForHR(hr); if (SecondaryScreen.SystemHasSecondaryScreen()) { // Add a DMO Wrapper Filter this.dmoFilter = (IBaseFilter) new DMOWrapperFilter(); this.dmoWrapperFilter = (IDMOWrapperFilter)this.dmoFilter; // But it is more useful to show how to scan for the DMO var g = this.FindGuid("DmoOverlay", DMOCategory.VideoEffect); hr = this.dmoWrapperFilter.Init(g, DMOCategory.VideoEffect); DMOError.ThrowExceptionForHR(hr); this.SetDMOParams(this.dmoFilter); // Add it to the Graph hr = this.graphBuilder.AddFilter(this.dmoFilter, "DMO Filter"); DsError.ThrowExceptionForHR(hr); var dmo = (IMediaObject)this.dmoFilter; hr = dmo.SetInputType(0, this.CreateVideoMediaType(24, resolution.Width, resolution.Height), DMOSetType.None); DsError.ThrowExceptionForHR(hr); hr = dmo.SetOutputType(0, this.CreateVideoMediaType(24, resolution.Width, resolution.Height), DMOSetType.None); DsError.ThrowExceptionForHR(hr); } // Get the video compressor and add it to the filter graph // Create the filter for the selected video compressor this.videoCompressorFilter = DirectShowUtils.CreateFilter( FilterCategory.VideoCompressorCategory, this.videoCompressorName); hr = this.graphBuilder.AddFilter(this.videoCompressorFilter, "Video Compressor"); DsError.ThrowExceptionForHR(hr); // Render the file writer portion of graph (mux -> file) hr = this.captureGraphBuilder.SetOutputFileName( MediaSubType.Avi, this.tempFilename, out this.muxFilter, out this.fileWriterFilter); DsError.ThrowExceptionForHR(hr); //// Disable overwrite //// hr = this.fileWriterFilter.SetMode(AMFileSinkFlags.None); //// DsError.ThrowExceptionForHR(hr); hr = this.captureGraphBuilder.AllocCapFile(this.tempFilename, 10000000); DsError.ThrowExceptionForHR(hr); if (SecondaryScreen.SystemHasSecondaryScreen()) { hr = this.captureGraphBuilder.RenderStream(null, null, this.screenCaptureFilter, null, this.smartTeeFilter); DsError.ThrowExceptionForHR(hr); hr = this.captureGraphBuilder.RenderStream( null, null, this.smartTeeFilter, this.videoCompressorFilter, this.muxFilter); DsError.ThrowExceptionForHR(hr); hr = this.captureGraphBuilder.RenderStream(null, null, this.smartTeeFilter, null, this.dmoFilter); DsError.ThrowExceptionForHR(hr); hr = this.captureGraphBuilder.RenderStream(null, null, this.dmoFilter, null, null); DsError.ThrowExceptionForHR(hr); } else { hr = this.captureGraphBuilder.RenderStream( null, null, this.screenCaptureFilter, this.videoCompressorFilter, this.muxFilter); DsError.ThrowExceptionForHR(hr); } // IMediaFilter filter = this.graphBuilder as IMediaFilter; // IReferenceClock clock; // filter.GetSyncSource(out clock); hr = this.graphBuilder.SetDefaultSyncSource(); DsError.ThrowExceptionForHR(hr); // Retreive the media control interface (for starting/stopping graph) this.mediaControl = (IMediaControl)this.graphBuilder; } catch (Exception ex) { ExceptionMethods.HandleException(ex); return(false); } return(true); }