saper_2

Form1.cs [MyPlayCap]

Nov 25th, 2012
38
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 12.28 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.Diagnostics;
  10. using System.Runtime.InteropServices;
  11.  
  12. using DirectShowLib;
  13. using System.Runtime.InteropServices.ComTypes;
  14.  
  15. namespace DirectShow_CameraCaptureMyTest
  16. {
  17.     public partial class Form1 : Form
  18.     {
  19.         public Form1()
  20.         {
  21.             InitializeComponent();
  22.         }
  23.  
  24.         // a small enum to record the graph state
  25.         enum PlayState { Stopped, Paused, Running, Init };
  26.  
  27.         // Application-defined message to notify app of filtergraph events
  28.         public const int WM_GRAPHNOTIFY = 0x8000 + 1;
  29.  
  30.         IVideoWindow videoWindow = null;
  31.         IMediaControl mediaControl = null;
  32.         IMediaEventEx mediaEventEx = null;
  33.         IGraphBuilder graphBuilder = null;
  34.         ICaptureGraphBuilder2 captureGraphBuilder = null;
  35.         PlayState currentState = PlayState.Stopped;
  36.  
  37.         DsROTEntry rot = null;
  38.  
  39.         public void CaptureVideo()
  40.         {
  41.             int hr = 0;
  42.             IBaseFilter sourceFilter = null;
  43.  
  44.             try
  45.             {
  46.                 // Get DirectShow interfaces
  47.                 GetInterfaces();
  48.  
  49.                 // Attach the filter graph to the capture graph
  50.                 hr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder);
  51.                 DsError.ThrowExceptionForHR(hr);
  52.  
  53.                 // Use the system device enumerator and class enumerator to find
  54.                 // a video capture/preview device, such as a desktop USB video camera.
  55.                 sourceFilter = FindCaptureDevice();
  56.  
  57.                 // Add Capture filter to our graph.
  58.                 hr = this.graphBuilder.AddFilter(sourceFilter, "Video Capture");
  59.                 DsError.ThrowExceptionForHR(hr);
  60.  
  61.                 // Render the preview pin on the video capture filter
  62.                 // Use this instead of this.graphBuilder.RenderFile
  63.                 hr = this.captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, null, null);
  64.                 DsError.ThrowExceptionForHR(hr);
  65.  
  66.                 // Now that the filter has been added to the graph and we have
  67.                 // rendered its stream, we can release this reference to the filter.
  68.                 Marshal.ReleaseComObject(sourceFilter);
  69.  
  70.                 // Set video window style and position
  71.                 SetupVideoWindow();
  72.  
  73.                 // Add our graph to the running object table, which will allow
  74.                 // the GraphEdit application to "spy" on our graph
  75.                 rot = new DsROTEntry(this.graphBuilder);
  76.  
  77.                 // Start previewing video data
  78.                 hr = this.mediaControl.Run();
  79.                 DsError.ThrowExceptionForHR(hr);
  80.  
  81.                 // Remember current state
  82.                 this.currentState = PlayState.Running;
  83.             }
  84.             catch
  85.             {
  86.                 MessageBox.Show("An unrecoverable error has occurred.");
  87.             }
  88.         }
  89.  
  90.         // This version of FindCaptureDevice is provide for education only.
  91.         // A second version using the DsDevice helper class is define later.
  92.         public IBaseFilter FindCaptureDevice()
  93.         {
  94.             int hr = 0;
  95.             IEnumMoniker classEnum = null;
  96.             IMoniker[] moniker = new IMoniker[1];
  97.             object source = null;
  98.  
  99.             // Create the system device enumerator
  100.             ICreateDevEnum devEnum = (ICreateDevEnum)new CreateDevEnum();
  101.  
  102.             // Create an enumerator for the video capture devices
  103.             hr = devEnum.CreateClassEnumerator(FilterCategory.VideoInputDevice, out classEnum, 0);
  104.             DsError.ThrowExceptionForHR(hr);
  105.  
  106.             // The device enumerator is no more needed
  107.             Marshal.ReleaseComObject(devEnum);
  108.  
  109.             // If there are no enumerators for the requested type, then
  110.             // CreateClassEnumerator will succeed, but classEnum will be NULL.
  111.             if (classEnum == null)
  112.             {
  113.                 throw new ApplicationException("No video capture device was detected.\r\n\r\n" +
  114.                                                "This sample requires a video capture device, such as a USB WebCam,\r\n" +
  115.                                                "to be installed and working properly.  The sample will now close.");
  116.             }
  117.  
  118.             // Use the first video capture device on the device list.
  119.             // Note that if the Next() call succeeds but there are no monikers,
  120.             // it will return 1 (S_FALSE) (which is not a failure).  Therefore, we
  121.             // check that the return code is 0 (S_OK).
  122.             if (classEnum.Next(moniker.Length, moniker, IntPtr.Zero) == 0)
  123.             {
  124.                 // Bind Moniker to a filter object
  125.                 Guid iid = typeof(IBaseFilter).GUID;
  126.                 moniker[0].BindToObject(null, null, ref iid, out source);
  127.             }
  128.             else
  129.             {
  130.                 throw new ApplicationException("Unable to access video capture device!");
  131.             }
  132.  
  133.             // Release COM objects
  134.             Marshal.ReleaseComObject(moniker[0]);
  135.             Marshal.ReleaseComObject(classEnum);
  136.  
  137.             // An exception is thrown if cast fail
  138.             return (IBaseFilter)source;
  139.         }
  140.         /*
  141.             // Uncomment this version of FindCaptureDevice to use the DsDevice helper class
  142.             // (and comment the first version of course)
  143.             public IBaseFilter FindCaptureDevice()
  144.             {
  145.               System.Collections.ArrayList devices;
  146.               object source;
  147.  
  148.               // Get all video input devices
  149.               devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
  150.  
  151.               // Take the first device
  152.               DsDevice device = (DsDevice)devices[0];
  153.  
  154.               // Bind Moniker to a filter object
  155.               Guid iid = typeof(IBaseFilter).GUID;
  156.               device.Mon.BindToObject(null, null, ref iid, out source);
  157.  
  158.               // An exception is thrown if cast fail
  159.               return (IBaseFilter) source;
  160.             }
  161.         */
  162.         public void GetInterfaces()
  163.         {
  164.             int hr = 0;
  165.  
  166.             // An exception is thrown if cast fail
  167.             this.graphBuilder = (IGraphBuilder)new FilterGraph();
  168.             this.captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
  169.             this.mediaControl = (IMediaControl)this.graphBuilder;
  170.             this.videoWindow = (IVideoWindow)this.graphBuilder;
  171.             this.mediaEventEx = (IMediaEventEx)this.graphBuilder;
  172.  
  173.             hr = this.mediaEventEx.SetNotifyWindow(this.Handle, WM_GRAPHNOTIFY, IntPtr.Zero);
  174.             DsError.ThrowExceptionForHR(hr);
  175.         }
  176.  
  177.         public void CloseInterfaces()
  178.         {
  179.             // Stop previewing data
  180.             if (this.mediaControl != null)
  181.                 this.mediaControl.StopWhenReady();
  182.  
  183.             this.currentState = PlayState.Stopped;
  184.  
  185.             // Stop receiving events
  186.             if (this.mediaEventEx != null)
  187.                 this.mediaEventEx.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero);
  188.  
  189.             // Relinquish ownership (IMPORTANT!) of the video window.
  190.             // Failing to call put_Owner can lead to assert failures within
  191.             // the video renderer, as it still assumes that it has a valid
  192.             // parent window.
  193.             if (this.videoWindow != null)
  194.             {
  195.                 this.videoWindow.put_Visible(OABool.False);
  196.                 this.videoWindow.put_Owner(IntPtr.Zero);
  197.             }
  198.  
  199.             // Remove filter graph from the running object table
  200.             if (rot != null)
  201.             {
  202.                 rot.Dispose();
  203.                 rot = null;
  204.             }
  205.  
  206.             // Release DirectShow interfaces
  207.             Marshal.ReleaseComObject(this.mediaControl); this.mediaControl = null;
  208.             Marshal.ReleaseComObject(this.mediaEventEx); this.mediaEventEx = null;
  209.             Marshal.ReleaseComObject(this.videoWindow); this.videoWindow = null;
  210.             Marshal.ReleaseComObject(this.graphBuilder); this.graphBuilder = null;
  211.             Marshal.ReleaseComObject(this.captureGraphBuilder); this.captureGraphBuilder = null;
  212.         }
  213.  
  214.         public void SetupVideoWindow()
  215.         {
  216.             int hr = 0;
  217.  
  218.             // Set the video window to be a child of the main window
  219.             //hr = this.videoWindow.put_Owner(this.Handle);
  220.             hr = this.videoWindow.put_Owner(pictureBox1.Handle);
  221.             DsError.ThrowExceptionForHR(hr);
  222.  
  223.             hr = this.videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren);
  224.             DsError.ThrowExceptionForHR(hr);
  225.  
  226.             // Use helper function to position video window in client rect
  227.             // of main application window
  228.             ResizeVideoWindow();
  229.  
  230.             // Make the video window visible, now that it is properly positioned
  231.             hr = this.videoWindow.put_Visible(OABool.True);
  232.             DsError.ThrowExceptionForHR(hr);
  233.         }
  234.  
  235.         public void ResizeVideoWindow()
  236.         {
  237.             // Resize the video preview window to match owner window size
  238.             if (this.videoWindow != null)
  239.             {
  240.                 this.videoWindow.SetWindowPosition(0, 0, pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height);
  241.             }
  242.         }
  243.  
  244.         public void ChangePreviewState(bool showVideo)
  245.         {
  246.             int hr = 0;
  247.  
  248.             // If the media control interface isn't ready, don't call it
  249.             if (this.mediaControl == null)
  250.                 return;
  251.  
  252.             if (showVideo)
  253.             {
  254.                 if (this.currentState != PlayState.Running)
  255.                 {
  256.                     // Start previewing video data
  257.                     hr = this.mediaControl.Run();
  258.                     this.currentState = PlayState.Running;
  259.                 }
  260.             }
  261.             else
  262.             {
  263.                 // Stop previewing video data
  264.                 hr = this.mediaControl.StopWhenReady();
  265.                 this.currentState = PlayState.Stopped;
  266.             }
  267.         }
  268.  
  269.         public void HandleGraphEvent()
  270.         {
  271.             int hr = 0;
  272.             EventCode evCode;
  273.             IntPtr evParam1, evParam2;
  274.  
  275.             if (this.mediaEventEx == null)
  276.                 return;
  277.  
  278.             while (this.mediaEventEx.GetEvent(out evCode, out evParam1, out evParam2, 0) == 0)
  279.             {
  280.                 // Free event parameters to prevent memory leaks associated with
  281.                 // event parameter data.  While this application is not interested
  282.                 // in the received events, applications should always process them.
  283.                 hr = this.mediaEventEx.FreeEventParams(evCode, evParam1, evParam2);
  284.                 DsError.ThrowExceptionForHR(hr);
  285.  
  286.                 // Insert event processing code here, if desired
  287.             }
  288.         }
  289.  
  290.         protected override void WndProc(ref Message m)
  291.         {
  292.             switch (m.Msg)
  293.             {
  294.                 case WM_GRAPHNOTIFY:
  295.                     {
  296.                         HandleGraphEvent();
  297.                         break;
  298.                     }
  299.             }
  300.  
  301.             // Pass this message to the video window for notification of system changes
  302.             if (this.videoWindow != null)
  303.                 this.videoWindow.NotifyOwnerMessage(m.HWnd, m.Msg, m.WParam, m.LParam);
  304.  
  305.             base.WndProc(ref m);
  306.         }
  307.  
  308.         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  309.         {
  310.             CloseInterfaces();
  311.         }
  312.  
  313.         private void Form1_Shown(object sender, EventArgs e)
  314.         {
  315.             CaptureVideo();
  316.         }
  317.  
  318.         private void Form1_Resize(object sender, EventArgs e)
  319.         {
  320.             // Stop graph when Form is iconic
  321.             if (this.WindowState == FormWindowState.Minimized)
  322.                 ChangePreviewState(false);
  323.  
  324.             // Restart Graph when window come back to normal state
  325.             if (this.WindowState == FormWindowState.Normal)
  326.                 ChangePreviewState(true);
  327.  
  328.             ResizeVideoWindow();
  329.  
  330.         }
  331.  
  332.  
  333.  
  334.     }
  335. }
Advertisement
Add Comment
Please, Sign In to add comment