代码之家  ›  专栏  ›  技术社区  ›  Max Schmeling

如何使用DirectShow.net获取视频帧?

  •  2
  • Max Schmeling  · 技术社区  · 15 年前

    作为程序的一部分,我必须能够从用户指定的视频文件中提取一些随机帧。我没有视频处理编程的经验,所以这对我来说是新的。

    我已经确定需要使用DirectShow.net在使用.NET的Windows XP上执行此操作,但我无法确定如何完成。我正在尝试使用isampleGrabber接口,但我无法完全弄清楚,也找不到任何示例。

    Internet上很少有使用DirectShow.net的例子,但肯定有人从使用.NET的视频中提取了帧,所以我只是想看看是否有人知道这样做的示例代码或是类似的代码。

    尝试跟随此代码项目文章,我想出了以下代码:

    // step 1
    IGraphBuilder graphBuilder = (IGraphBuilder)new FilterGraph();
    
    // step 2
    IBaseFilter grabberBaseFilter;
    ISampleGrabber sampleGrabber;
    AMMediaType mt;
    grabberBaseFilter = (IBaseFilter)new SampleGrabber();
    sampleGrabber = (ISampleGrabber)grabberBaseFilter;
    graphBuilder.AddFilter(grabberBaseFilter, "Grabber");
    
    // step 3
    
    mt = new AMMediaType();
    mt.majorType = MediaType.Video;
    mt.subType = MediaSubType.RGB24;
    mt.formatType = FormatType.VideoInfo;
    sampleGrabber.SetMediaType(mt);
    graphBuilder.RenderFile(filename, null);
    
    IMediaControl mediaControl = (IMediaControl)graphBuilder;
    IMediaEvent mediaEventEx = (IMediaEvent)graphBuilder;
    
    sampleGrabber.SetBufferSamples(true);
    sampleGrabber.SetOneShot(true);
    
    // step 4
    
    mediaControl.Run();
    
    EventCode evCode;
    mediaEventEx.WaitForCompletion(int.MaxValue, out evCode);
    
    AMMediaType connectedMediaType = new AMMediaType();
    sampleGrabber.GetConnectedMediaType(connectedMediaType);
    
    VideoInfoHeader videoHeader = (VideoInfoHeader)connectedMediaType.formatType;
    
    BitmapInfo bitmapInfo = new BitmapInfo();
    bitmapInfo.bmiHeader = videoHeader.BmiHeader;
    
    // ::CreateDIBSection(0, &BitmapInfo, DIB_RGB_COLORS, &buffer, NULL, 0); 
    // legacy - GdiFlush(); 
    
    // Copy the image into the buffer. 
    int size = 0;
    sampleGrabber.GetCurrentBuffer(ref size, buffer);
    

    由于没有缓冲区变量,所以不会编译的部分是videoheader cast行和结尾的getcurrentBuffer行。但我不知道该怎么做才能修好它。

    3 回复  |  直到 14 年前
        1
  •  1
  •   Jeremiah Morrill    15 年前

    尝试使用IMediadet。 Here is a sample 从我的项目;

        2
  •  1
  •   Yuriy Zanichkovskyy    14 年前

    更好的解决方案是使用ibasicvideo.getcurrenteimage方法。它更通用,适用于大多数视频。

        3
  •  1
  •   Boyan Kostadinov    14 年前

    将其更改为:

    VideoInfoHeader videoHeader = (VideoInfoHeader)Marshal.PtrToStructure(connectedMediaType.formatPtr, typeof(VideoInfoHeader));