1

我目前正在尝试将 ISampleGrabber 过滤器添加到我的程序中。目前,该程序捕获并显示预览到我的 Windows 窗体,但是当我尝试使用其他示例添加我自己的 ISampleGrabber 过滤器时,程序的网络摄像头部分完全停止工作。

    IVideoWindow videoWindow = null;
    IMediaControl mediaControl = null;
    IMediaEventEx mediaEventEx = null;
    IGraphBuilder graphBuilder = null;
    ICaptureGraphBuilder2 captureGraphBuilder = null;
    IBaseFilter baseFilterForSampleGrabber;
    ISampleGrabber sampleGrabber;
    AMMediaType mediaType;
    VideoInfoHeader videoInfoHeader;

public void capturePreview()
{        
    int hr = 0;
    IBaseFilter baseFilter = null;
    try
    {

            interfaces();

            hr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder);
            DsError.ThrowExceptionForHR(hr);

            baseFilter = getListOfDevices();

            hr = this.graphBuilder.AddFilter(baseFilter, "Webcam");
            DsError.ThrowExceptionForHR(hr);



            sampleGrabber = new SampleGrabber() as ISampleGrabber;
            baseFilterForSampleGrabber = (IBaseFilter)new SampleGrabber();

            if (baseFilterForSampleGrabber == null)
            {
                Marshal.ReleaseComObject(sampleGrabber);
                sampleGrabber = null;
            }                

            mediaType = new AMMediaType();
            mediaType.majorType = MediaType.Video;
            mediaType.subType = MediaSubType.RGB24;  
            mediaType.formatType = FormatType.VideoInfo;
            //int width = videoInfoHeader.BmiHeader.Width;
            //int height = videoInfoHeader.BmiHeader.Height;
            //int size = videoInfoHeader.BmiHeader.ImageSize;
            //mediaType.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(videoInfoHeader));
            //Marshal.StructureToPtr(videoInfoHeader, mediaType.formatPtr, false);
            hr = sampleGrabber.SetMediaType(mediaType);
            DsUtils.FreeAMMediaType(mediaType);





            hr = graphBuilder.AddFilter(baseFilterForSampleGrabber, "ISampleGrabber Filter");
            DsError.ThrowExceptionForHR(hr);  

            hr = this.captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, baseFilter, baseFilterForSampleGrabber, null);
            DsError.ThrowExceptionForHR(hr);                

            Marshal.ReleaseComObject(baseFilter);

            videoWindowSetup();

            hr = sampleGrabber.SetBufferSamples(true);
            DsError.ThrowExceptionForHR(hr);

            hr = this.mediaControl.Run();
            DsError.ThrowExceptionForHR(hr);







    }
    catch
    {
        MessageBox.Show("Error...Try restart");
    }



}

上面的代码包含我当前的图表以及我在每个示例中看到的重复的起始 ISampleGrabber 代码,但是当我添加注释代码时,这是程序停止的时候。我不知道问题出在哪里,并假设我至少应该在继续添加图表之前对基础知识进行排序。

如果我解决了这个问题,对完成此图表所需的任何其他帮助将非常有帮助,我的目标是将捕获的帧转换为位图,以便我可以立即编辑它们,例如添加十字准线,并在窗口中显示它们表格一旦被立即编辑。

任何帮助表示赞赏:)

4

1 回答 1

1

注释代码未正确初始化videoInfoHeader。您需要在那里初始化所有成员(好吧,有些可能会留下零,但您必须为强制性成员添加值)。biCompressionbiBitCount至少可以这么说。此外,您的代码甚至不会初始化这些成员,反之亦然会读回未初始化的值。

然而,这已经是错误的方式了。大多数示例表明您不进行初始化是formatformatPtr原因的。对于主要类型和子类型,Sample Grabber 会“提示”智能连接您想要的数据格式(此处通常为 24 位 RGB)。是的,这是您可以做的,而且效果很好。但是,那里没有指定分辨率或帧速率的灵活性,甚至不是每种像素格式都适用。也就是说,您在这里尝试做的任何事情都可能是不正确的。您应该对部分媒体类型(仅主要类型和子类型)感到满意。

DxScan来自 DirectShow.NET Samples 添加了 Sample Grabber 并展示了如何进行以及如何设置它:

    private void ConfigureSampleGrabber(ISampleGrabber sampGrabber)
    {
        AMMediaType media;
        int hr;

        // Set the media type to Video/RBG24
        media = new AMMediaType();
        media.majorType = MediaType.Video;
        media.subType   = MediaSubType.RGB24;
        media.formatType = FormatType.VideoInfo;
        hr = sampGrabber.SetMediaType( media );
        DsError.ThrowExceptionForHR( hr );

        DsUtils.FreeAMMediaType(media);
        media = null;

        // Choose to call BufferCB instead of SampleCB
        hr = sampGrabber.SetCallback( this, 1 );
        DsError.ThrowExceptionForHR( hr );
    }
于 2013-10-16T20:14:02.547 回答