DirectShow USB网络摄像头改变视频源

时间:2013-07-17 01:44:20

标签: c# video webcam directshow image-capture

嘿所有我想在我的网络摄像头上找到将我的视频源更改为“复合”的设置。似乎如果我拔下USB然后将其重新插入并启动代码,它就会出现一个空白屏幕。但是,一旦我更改了视频源(在另一个程序中),然后返回并再次运行我的代码,它就会显示出来。

所以我需要一些能让我改变它的东西,以便在我自己的应用程序中发生同样的事情而不必启动另一个具有该功能来设置网络摄像头的程序。

当我拔出USB线然后将其重新插入并运行源代码时,应用程序的图片框为黑色。

enter image description here

我用来改变视频源的“其他程序”(似乎可以调出图像): enter image description here

在我使用“其他程序”后,我回到源代码并运行它,这就是我得到的: enter image description here

我从这里使用名为dot Net Webcam Library的C#代码:enter link description here

似乎使用enter link description here

中的DirectShow

我在源代码中注意到它列出了不同类型的视频设置(在下面的AXExtend.cs中找到):

public enum PhysicalConnectorType
{
    Video_Tuner = 1,
    Video_Composite,
    Video_SVideo,
    Video_RGB,
    Video_YRYBY,
    Video_SerialDigital,
    Video_ParallelDigital,
    Video_SCSI,
    Video_AUX,
    Video_1394,
    Video_USB,
    Video_VideoDecoder,
    Video_VideoEncoder,
    Video_SCART,
    Video_Black,

    Audio_Tuner = 0x1000,
    Audio_Line,
    Audio_Mic,
    Audio_AESDigital,
    Audio_SPDIFDigital,
    Audio_SCSI,
    Audio_AUX,
    Audio_1394,
    Audio_USB,
    Audio_AudioDecoder,
}

但我不确定如何在代码中调用它:

Device selectedDevice = device as Device;
imageCapture.Device = selectedDevice as Device;
imageCapture.PerformAutoScale();
imageCapture.Refresh();
imageCapture.Start();

所以我猜测“Video_Composite”是我可能需要做的吗?

任何帮助都会很棒!!!谢谢!

大卫

代码更新

foreach (Device device in Device.FindDevices())
{
   if (device.ToString() == "BackupCamera")
    {
        Device selectedDevice = device as Device;
        IGraphBuilder graphBuilder = new FilterGraph() as IGraphBuilder;
        DsDevice device1 = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice)[1]; // <<--- Your Device
        Guid baseFilterIdentifier = typeof(IBaseFilter).GUID;
        object videoSourceObject;
        device1.Mon.BindToObject(null, null, ref baseFilterIdentifier, out videoSourceObject);
        IBaseFilter videoSourceBaseFilter = videoSourceObject as IBaseFilter;
        graphBuilder.AddFilter(videoSourceBaseFilter, "Source");
        ICaptureGraphBuilder2 captureGraphBuilder = new CaptureGraphBuilder2() as ICaptureGraphBuilder2;
        captureGraphBuilder.SetFiltergraph(graphBuilder);
        object crossbarObject;
        captureGraphBuilder.FindInterface(FindDirection.UpstreamOnly, null, videoSourceBaseFilter, typeof(IAMCrossbar).GUID, out crossbarObject);
        IAMCrossbar crossbar = crossbarObject as IAMCrossbar;
        int inputPinCount, outputPinCount;
        crossbar.get_PinCounts(out inputPinCount, out outputPinCount); // <<-- In/Out Pins
        // Pin Selection: Physical Input 2 (e.g. Composite) to Capture Pin 0 
        crossbar.Route(0, 2);

        imageCapture.Device = selectedDevice as Device;
        imageCapture.PerformAutoScale();
        imageCapture.Refresh();
        imageCapture.Start();
    }
}

1 个答案:

答案 0 :(得分:3)

在运行文件管理器图之前,您需要获取交叉开关界面。您通常会使用ICaptureGraphBuilder2::FindInterface。这需要一个额外的过滤器,FindInterface方法特别适用于这个原因:

  

支持过滤器。如果捕获设备使用Windows驱动程序模型(WDM)驱动程序,则图形可能需要WDM视频捕获过滤器上游的某些过滤器,例如电视调谐器滤波器或模拟视频交叉开关过滤器。如果pCategory参数不等于NULL,则此方法会自动将任何所需的WDM过滤器插入到图表中

完成此操作后,您将拥有IAMCrossbar界面,并且IAMCrossbar::Route方法是您切换输入的方式。

另请参阅:Crossbar filter change current input to Composite

代码段:

IGraphBuilder graphBuilder = new FilterGraph() as IGraphBuilder;
DsDevice device = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice)[1]; // <<--- Your Device
Guid baseFilterIdentifier = typeof(IBaseFilter).GUID;
object videoSourceObject;
device.Mon.BindToObject(null, null, ref baseFilterIdentifier, out videoSourceObject);
IBaseFilter videoSourceBaseFilter = videoSourceObject as IBaseFilter;
graphBuilder.AddFilter(videoSourceBaseFilter, "Source");
ICaptureGraphBuilder2 captureGraphBuilder = new CaptureGraphBuilder2() as ICaptureGraphBuilder2;
captureGraphBuilder.SetFiltergraph(graphBuilder);
object crossbarObject;
captureGraphBuilder.FindInterface(FindDirection.UpstreamOnly, null, videoSourceBaseFilter, typeof(IAMCrossbar).GUID, out crossbarObject);
IAMCrossbar crossbar = crossbarObject as IAMCrossbar;
int inputPinCount, outputPinCount;
crossbar.get_PinCounts(out inputPinCount, out outputPinCount); // <<-- In/Out Pins
// Pin Selection: Physical Input 2 (e.g. Composite) to Capture Pin 0 
crossbar.Route(0, 2);