웹캠 캡쳐
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DirectShowLib;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace CastCommon
{
public class WebCamCapturer
{
// a small enum to record the graph state
enum PlayState
{
Stopped,
Paused,
Running,
Init
};
// Application-defined message to notify app of filtergraph events
public const int WM_GRAPHNOTIFY = 0x8000 + 1;
IVideoWindow videoWindow = null;
IMediaControl mediaControl = null;
IMediaEventEx mediaEventEx = null;
IGraphBuilder graphBuilder = null;
ICaptureGraphBuilder2 captureGraphBuilder = null;
PlayState currentState = PlayState.Stopped;
DsROTEntry rot = null;
public void CaptureVideo(Control control)
{
int hr = 0;
IBaseFilter sourceFilter = null;
try
{
// Get DirectShow interfaces
GetInterfaces(control);
// Attach the filter graph to the capture graph
hr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder);
DsError.ThrowExceptionForHR(hr);
// Use the system device enumerator and class enumerator to find
// a video capture/preview device, such as a desktop USB video camera.
sourceFilter = FindCaptureDevice();
// Add Capture filter to our graph.
hr = this.graphBuilder.AddFilter(sourceFilter, "Video Capture");
DsError.ThrowExceptionForHR(hr);
// Render the preview pin on the video capture filter
// Use this instead of this.graphBuilder.RenderFile
hr = this.captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, null, null);
DsError.ThrowExceptionForHR(hr);
// Now that the filter has been added to the graph and we have
// rendered its stream, we can release this reference to the filter.
Marshal.ReleaseComObject(sourceFilter);
// Set video window style and position
SetupVideoWindow(control);
// Add our graph to the running object table, which will allow
// the GraphEdit application to "spy" on our graph
rot = new DsROTEntry(this.graphBuilder);
// Start previewing video data
hr = this.mediaControl.Run();
DsError.ThrowExceptionForHR(hr);
// Remember current state
this.currentState = PlayState.Running;
}
catch
{
MessageBox.Show("An unrecoverable error has occurred.");
}
}
public void GetInterfaces(Control control)
{
int hr = 0;
// An exception is thrown if cast fail
this.graphBuilder = (IGraphBuilder)new FilterGraph();
this.captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
this.mediaControl = (IMediaControl)this.graphBuilder;
this.videoWindow = (IVideoWindow)this.graphBuilder;
this.mediaEventEx = (IMediaEventEx)this.graphBuilder;
hr = this.mediaEventEx.SetNotifyWindow(control.Handle, WM_GRAPHNOTIFY, IntPtr.Zero);
DsError.ThrowExceptionForHR(hr);
}
// This version of FindCaptureDevice is provide for education only.
// A second version using the DsDevice helper class is define later.
public IBaseFilter FindCaptureDevice()
{
int hr = 0;
#if USING_NET11
UCOMIEnumMoniker classEnum = null;
UCOMIMoniker[] moniker = new UCOMIMoniker[1];
#else
IEnumMoniker classEnum = null;
IMoniker[] moniker = new IMoniker[1];
#endif
object source = null;
// Create the system device enumerator
ICreateDevEnum devEnum = (ICreateDevEnum)new CreateDevEnum();
// Create an enumerator for the video capture devices
hr = devEnum.CreateClassEnumerator(FilterCategory.VideoInputDevice, out classEnum, 0);
DsError.ThrowExceptionForHR(hr);
// The device enumerator is no more needed
Marshal.ReleaseComObject(devEnum);
// If there are no enumerators for the requested type, then
// CreateClassEnumerator will succeed, but classEnum will be NULL.
if (classEnum == null)
{
throw new ApplicationException("No video capture device was detected.\r\n\r\n" +
"This sample requires a video capture device, such as a USB WebCam,\r\n" +
"to be installed and working properly. The sample will now close.");
}
// Use the first video capture device on the device list.
// Note that if the Next() call succeeds but there are no monikers,
// it will return 1 (S_FALSE) (which is not a failure). Therefore, we
// check that the return code is 0 (S_OK).
#if USING_NET11
int i;
if (classEnum.Next (moniker.Length, moniker, IntPtr.Zero) == 0)
#else
if (classEnum.Next(moniker.Length, moniker, IntPtr.Zero) == 0)
#endif
{
// Bind Moniker to a filter object
Guid iid = typeof(IBaseFilter).GUID;
moniker[0].BindToObject(null, null, ref iid, out source);
}
else
{
throw new ApplicationException("Unable to access video capture device!");
}
// Release COM objects
Marshal.ReleaseComObject(moniker[0]);
Marshal.ReleaseComObject(classEnum);
// An exception is thrown if cast fail
return (IBaseFilter)source;
}
/*
// Uncomment this version of FindCaptureDevice to use the DsDevice helper class
// (and comment the first version of course)
public IBaseFilter FindCaptureDevice()
{
System.Collections.ArrayList devices;
object source;
// Get all video input devices
devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
// Take the first device
DsDevice device = (DsDevice)devices[0];
// Bind Moniker to a filter object
Guid iid = typeof(IBaseFilter).GUID;
device.Mon.BindToObject(null, null, ref iid, out source);
// An exception is thrown if cast fail
return (IBaseFilter) source;
}
*/
public void SetupVideoWindow(Control control)
{
int hr = 0;
// Set the video window to be a child of the main window
hr = this.videoWindow.put_Owner(control.Handle);
DsError.ThrowExceptionForHR(hr);
hr = this.videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren);
DsError.ThrowExceptionForHR(hr);
// Use helper function to position video window in client rect
// of main application window
ResizeVideoWindow(control);
// Make the video window visible, now that it is properly positioned
hr = this.videoWindow.put_Visible(OABool.True);
DsError.ThrowExceptionForHR(hr);
}
public void ResizeVideoWindow(Control control)
{
// Resize the video preview window to match owner window size
if (this.videoWindow != null)
{
this.videoWindow.SetWindowPosition(0, 0, control.ClientSize.Width, control.ClientSize.Height);
}
}
// Stop capturing and release interfaces
public void CloseInterfaces()
{
// Stop previewing data
if (this.mediaControl != null)
this.mediaControl.StopWhenReady();
this.currentState = PlayState.Stopped;
// Stop receiving events
if (this.mediaEventEx != null)
this.mediaEventEx.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero);
// Relinquish ownership (IMPORTANT!) of the video window.
// Failing to call put_Owner can lead to assert failures within
// the video renderer, as it still assumes that it has a valid
// parent window.
if (this.videoWindow != null)
{
this.videoWindow.put_Visible(OABool.False);
this.videoWindow.put_Owner(IntPtr.Zero);
}
// Remove filter graph from the running object table
if (rot != null)
{
rot.Dispose();
rot = null;
}
// Release DirectShow interfaces
Marshal.ReleaseComObject(this.mediaControl); this.mediaControl = null;
Marshal.ReleaseComObject(this.mediaEventEx); this.mediaEventEx = null;
Marshal.ReleaseComObject(this.videoWindow); this.videoWindow = null;
Marshal.ReleaseComObject(this.graphBuilder); this.graphBuilder = null;
Marshal.ReleaseComObject(this.captureGraphBuilder); this.captureGraphBuilder = null;
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DirectShowLib;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace CastCommon
{
public class WebCamCapturer
{
// a small enum to record the graph state
enum PlayState
{
Stopped,
Paused,
Running,
Init
};
// Application-defined message to notify app of filtergraph events
public const int WM_GRAPHNOTIFY = 0x8000 + 1;
IVideoWindow videoWindow = null;
IMediaControl mediaControl = null;
IMediaEventEx mediaEventEx = null;
IGraphBuilder graphBuilder = null;
ICaptureGraphBuilder2 captureGraphBuilder = null;
PlayState currentState = PlayState.Stopped;
DsROTEntry rot = null;
public void CaptureVideo(Control control)
{
int hr = 0;
IBaseFilter sourceFilter = null;
try
{
// Get DirectShow interfaces
GetInterfaces(control);
// Attach the filter graph to the capture graph
hr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder);
DsError.ThrowExceptionForHR(hr);
// Use the system device enumerator and class enumerator to find
// a video capture/preview device, such as a desktop USB video camera.
sourceFilter = FindCaptureDevice();
// Add Capture filter to our graph.
hr = this.graphBuilder.AddFilter(sourceFilter, "Video Capture");
DsError.ThrowExceptionForHR(hr);
// Render the preview pin on the video capture filter
// Use this instead of this.graphBuilder.RenderFile
hr = this.captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, null, null);
DsError.ThrowExceptionForHR(hr);
// Now that the filter has been added to the graph and we have
// rendered its stream, we can release this reference to the filter.
Marshal.ReleaseComObject(sourceFilter);
// Set video window style and position
SetupVideoWindow(control);
// Add our graph to the running object table, which will allow
// the GraphEdit application to "spy" on our graph
rot = new DsROTEntry(this.graphBuilder);
// Start previewing video data
hr = this.mediaControl.Run();
DsError.ThrowExceptionForHR(hr);
// Remember current state
this.currentState = PlayState.Running;
}
catch
{
MessageBox.Show("An unrecoverable error has occurred.");
}
}
public void GetInterfaces(Control control)
{
int hr = 0;
// An exception is thrown if cast fail
this.graphBuilder = (IGraphBuilder)new FilterGraph();
this.captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
this.mediaControl = (IMediaControl)this.graphBuilder;
this.videoWindow = (IVideoWindow)this.graphBuilder;
this.mediaEventEx = (IMediaEventEx)this.graphBuilder;
hr = this.mediaEventEx.SetNotifyWindow(control.Handle, WM_GRAPHNOTIFY, IntPtr.Zero);
DsError.ThrowExceptionForHR(hr);
}
// This version of FindCaptureDevice is provide for education only.
// A second version using the DsDevice helper class is define later.
public IBaseFilter FindCaptureDevice()
{
int hr = 0;
#if USING_NET11
UCOMIEnumMoniker classEnum = null;
UCOMIMoniker[] moniker = new UCOMIMoniker[1];
#else
IEnumMoniker classEnum = null;
IMoniker[] moniker = new IMoniker[1];
#endif
object source = null;
// Create the system device enumerator
ICreateDevEnum devEnum = (ICreateDevEnum)new CreateDevEnum();
// Create an enumerator for the video capture devices
hr = devEnum.CreateClassEnumerator(FilterCategory.VideoInputDevice, out classEnum, 0);
DsError.ThrowExceptionForHR(hr);
// The device enumerator is no more needed
Marshal.ReleaseComObject(devEnum);
// If there are no enumerators for the requested type, then
// CreateClassEnumerator will succeed, but classEnum will be NULL.
if (classEnum == null)
{
throw new ApplicationException("No video capture device was detected.\r\n\r\n" +
"This sample requires a video capture device, such as a USB WebCam,\r\n" +
"to be installed and working properly. The sample will now close.");
}
// Use the first video capture device on the device list.
// Note that if the Next() call succeeds but there are no monikers,
// it will return 1 (S_FALSE) (which is not a failure). Therefore, we
// check that the return code is 0 (S_OK).
#if USING_NET11
int i;
if (classEnum.Next (moniker.Length, moniker, IntPtr.Zero) == 0)
#else
if (classEnum.Next(moniker.Length, moniker, IntPtr.Zero) == 0)
#endif
{
// Bind Moniker to a filter object
Guid iid = typeof(IBaseFilter).GUID;
moniker[0].BindToObject(null, null, ref iid, out source);
}
else
{
throw new ApplicationException("Unable to access video capture device!");
}
// Release COM objects
Marshal.ReleaseComObject(moniker[0]);
Marshal.ReleaseComObject(classEnum);
// An exception is thrown if cast fail
return (IBaseFilter)source;
}
/*
// Uncomment this version of FindCaptureDevice to use the DsDevice helper class
// (and comment the first version of course)
public IBaseFilter FindCaptureDevice()
{
System.Collections.ArrayList devices;
object source;
// Get all video input devices
devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
// Take the first device
DsDevice device = (DsDevice)devices[0];
// Bind Moniker to a filter object
Guid iid = typeof(IBaseFilter).GUID;
device.Mon.BindToObject(null, null, ref iid, out source);
// An exception is thrown if cast fail
return (IBaseFilter) source;
}
*/
public void SetupVideoWindow(Control control)
{
int hr = 0;
// Set the video window to be a child of the main window
hr = this.videoWindow.put_Owner(control.Handle);
DsError.ThrowExceptionForHR(hr);
hr = this.videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren);
DsError.ThrowExceptionForHR(hr);
// Use helper function to position video window in client rect
// of main application window
ResizeVideoWindow(control);
// Make the video window visible, now that it is properly positioned
hr = this.videoWindow.put_Visible(OABool.True);
DsError.ThrowExceptionForHR(hr);
}
public void ResizeVideoWindow(Control control)
{
// Resize the video preview window to match owner window size
if (this.videoWindow != null)
{
this.videoWindow.SetWindowPosition(0, 0, control.ClientSize.Width, control.ClientSize.Height);
}
}
// Stop capturing and release interfaces
public void CloseInterfaces()
{
// Stop previewing data
if (this.mediaControl != null)
this.mediaControl.StopWhenReady();
this.currentState = PlayState.Stopped;
// Stop receiving events
if (this.mediaEventEx != null)
this.mediaEventEx.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero);
// Relinquish ownership (IMPORTANT!) of the video window.
// Failing to call put_Owner can lead to assert failures within
// the video renderer, as it still assumes that it has a valid
// parent window.
if (this.videoWindow != null)
{
this.videoWindow.put_Visible(OABool.False);
this.videoWindow.put_Owner(IntPtr.Zero);
}
// Remove filter graph from the running object table
if (rot != null)
{
rot.Dispose();
rot = null;
}
// Release DirectShow interfaces
Marshal.ReleaseComObject(this.mediaControl); this.mediaControl = null;
Marshal.ReleaseComObject(this.mediaEventEx); this.mediaEventEx = null;
Marshal.ReleaseComObject(this.videoWindow); this.videoWindow = null;
Marshal.ReleaseComObject(this.graphBuilder); this.graphBuilder = null;
Marshal.ReleaseComObject(this.captureGraphBuilder); this.captureGraphBuilder = null;
}
}
}
댓글
댓글 쓰기