播放与颜色转换器DMO失真跳绳



我正在处理另一个directshow图表,似乎无法理解我所看到的问题。当我在graphhedit中将图形组合在一起时它会显示:

filesource -> demux -> decoder -> color converter -> dmo -> external render

这工作完美,回放是惊人的!

但是在代码中(和图形构建完美没有错误)…它不能做我想要的……相反,它播放文件,但播放非常像素化和黑暗,它看起来像是跳过了前一帧的顶部,从未删除前一帧。

下面是我的代码:

private static void BuildGraph(IGraphBuilder pGraph, string source)
{
    int hr = 0;
    // Graph builder.
    pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
    hr = pBuilder.SetFiltergraph(pGraph);
    CheckHR(hr, "Can't SetFiltergraph.");
    // Add File Source (Async.).
    pFileSourceAsync = (IBaseFilter)new AsyncReader();
    hr = pGraph.AddFilter(pFileSourceAsync, "File Source (Async.)");
    CheckHR(hr, "Can't add File Source (Async.) to graph.");
    // Set source filename.
    pFileSourceAsync_src = pFileSourceAsync as IFileSourceFilter;
    if (pFileSourceAsync_src == null)
    {
        CheckHR(unchecked((int)0x80004002), "Can't get IFileSourceFilter.");
    }
    hr = pFileSourceAsync_src.Load(source, null);
    CheckHR(hr, "Can't load file.");
    // Add MPEG4 Demultiplexor.
    pMPEG4Demultiplexor = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_MPEG4Demultiplexor));
    hr = pGraph.AddFilter(pMPEG4Demultiplexor, "MPEG4 Demultiplexor");
    CheckHR(hr, "Can't add MPEG4 Demultiplexor to graph.");
    // Add Microsoft DTV-DVD Video Decoder.
    pMicrosoftDTVDVDVideoDecoder = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_MicrosoftDTVDVDVideoDecoder));
    hr = pGraph.AddFilter(pMicrosoftDTVDVDVideoDecoder, "Microsoft DTV-DVD Video Decoder");
    CheckHR(hr, "Can't add Microsoft DTV-DVD Video Decoder to graph.");
    // Add Color Converter DMO.
    dmoFilter = (IBaseFilter)new DMOWrapperFilter();
    dmoWrapper = (IDMOWrapperFilter)dmoFilter;
    hr = dmoWrapper.Init(CLSID_ColorConverterDMO, DMOCategory.VideoEffect);
    CheckHR(hr, "Can't initialize Color Converter DMO.");
    hr = pGraph.AddFilter(dmoFilter, "DMO Filter");
    CheckHR(hr, "Can't add Color Converter DMO to graph.");

    //IMediaParams dmoParams = dmoFilter as IMediaParams;
    //MPData srcLeft = new MPData();
    //MPData srcTop = new MPData();
    //MPData destLeft = new MPData();
    //MPData destTop = new MPData();
    //MPData width = new MPData();
    //MPData height = new MPData();
    //srcLeft.vFloat = 0;
    //srcTop.vFloat = 0;
    //destLeft.vFloat = 0;
    //destTop.vFloat = 0;
    //width.vFloat = 1280;
    //height.vFloat = 720;
    //dmoParams.SetParam(0, srcLeft);
    //dmoParams.SetParam(1, srcTop);
    //dmoParams.SetParam(2, destLeft);
    //dmoParams.SetParam(3, destTop);
    //dmoParams.SetParam(4, width);
    //dmoParams.SetParam(5, height);

    // Add Smart Tee.
    pSmartTee = (IBaseFilter)new SmartTee();
    hr = pGraph.AddFilter(pSmartTee, "Smart Tee");
    CheckHR(hr, "Can't add Smart Tee to graph.");
    // Add Decklink Video Render.
    pDecklinkVideoRender = CreateFilterByName(@"Decklink Video Render", CLSID_ExternalRenderers);
    hr = pGraph.AddFilter(pDecklinkVideoRender, "Decklink Video Render");
    CheckHR(hr, "Can't add Decklink Video Render to graph.");
    // Add AVI Decompressor.
    pAVIDecompressor = (IBaseFilter)new AVIDec();
    hr = pGraph.AddFilter(pAVIDecompressor, "AVI Decompressor");
    CheckHR(hr, "Can't add AVI Decompressor to graph.");
    // Add Color Space Converter.
    pColorSpaceConverter = (IBaseFilter)new Colour();
    hr = pGraph.AddFilter(pColorSpaceConverter, "Color Space Converter");
    CheckHR(hr, "Can't add Color Space Converter to graph.");
    // Add Null Renderer.
    pNullRenderer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_NullRenderer));
    hr = pGraph.AddFilter(pNullRenderer, "Null Renderer");
    CheckHR(hr, "Can't add Null Renderer to graph.");
    // Connect File Source (Async.) and MPEG4 Demultiplexor.
    hr = pGraph.ConnectDirect(GetPin(pFileSourceAsync, "Output"), GetPin(pMPEG4Demultiplexor, "Input"), null);
    CheckHR(hr, "Can't connect File Source (Async.) and MPEG4 Demultiplexor.");
    // Connect MPEG4 Demultiplexor and Microsoft DTV-DVD Video Decoder.
    hr = pGraph.ConnectDirect(GetPin(pMPEG4Demultiplexor, "Video 1"), GetPin(pMicrosoftDTVDVDVideoDecoder, "Video Input"), null);
    CheckHR(hr, "Can't connect MPEG4 Demultiplexor and Microsoft DTV-DVD Video Decoder.");
    // Connect Microsoft DTV-DVD Video Decoder and Color Converter DMO.
    hr = pGraph.ConnectDirect(GetPin(pMicrosoftDTVDVDVideoDecoder, "Video Output 1"), GetPin(dmoFilter, "in0"), null);
    CheckHR(hr, "Can't connect Microsoft DTV-DVD Video Decoder and Color Converter DMO.");
    // Connect Color Converter DMO and Smart Tee Filter.
    hr = pGraph.ConnectDirect(GetPin(dmoFilter, "out0"), GetPin(pSmartTee, "Input"), null);
    CheckHR(hr, "Can't connect Color Converter DMO and Smart Tee Filter.");
    // Connect Smart Tee Filter and Decklink Video Render.
    hr = pGraph.ConnectDirect(GetPin(pSmartTee, "Capture"), GetPin(pDecklinkVideoRender, "In"), null);
    CheckHR(hr, "Can't connect Smart Tee Filter and Decklink Video Render.");
    // Add SampleGrabber.
    pSampleGrabber = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_SampleGrabber));
    hr = pGraph.AddFilter(pSampleGrabber, "SampleGrabber");
    CheckHR(hr, "Can't add SampleGrabber to graph.");
    (pSampleGrabber as ISampleGrabber).SetBufferSamples(true);
    (pSampleGrabber as ISampleGrabber).SetOneShot(false);
    // Connect Smart Tee and SampleGrabber.
    hr = pGraph.ConnectDirect(GetPin(pSmartTee, "Preview"), GetPin(pSampleGrabber, "Input"), null);
    CheckHR(hr, "Can't connect Smart Tee and SampleGrabber.");
    // Connect SampleGrabber and AVIDecompressor.
    hr = pGraph.ConnectDirect(GetPin(pSampleGrabber, "Output"), GetPin(pAVIDecompressor, "XForm In"), null);
    CheckHR(hr, "Can't connect SampleGrabber and AVIDecompressor.");
    // Connect AVIDecompressor and Color Space Converter.
    hr = pGraph.ConnectDirect(GetPin(pAVIDecompressor, "XForm Out"), GetPin(pColorSpaceConverter, "Input"), null);
    CheckHR(hr, "Can't connect Color Space Converter and SampleGrabber.");
    // Connect Color Space Converter and Null Renderer.
    hr = pGraph.ConnectDirect(GetPin(pColorSpaceConverter, "XForm Out"), GetPin(pNullRenderer, "In"), null);
    CheckHR(hr, "Can't connect Color Space Converter and Null Renderer.");
    // Set SampleGrabber Media Type.
    AMMediaType pSampleGrabber_pmt = new AMMediaType();
    pSampleGrabber_pmt.majorType = MediaType.Video;
    pSampleGrabber_pmt.subType = MediaSubType.RGB32;
    pSampleGrabber_pmt.formatType = FormatType.VideoInfo;
    VideoInfoHeader pSampleGrabber_format = new VideoInfoHeader();
    pSampleGrabber_pmt.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(pSampleGrabber_format));
    Marshal.StructureToPtr(pSampleGrabber_format, pSampleGrabber_pmt.formatPtr, false);
    hr = ((ISampleGrabber)pSampleGrabber).SetMediaType(pSampleGrabber_pmt);
    DsUtils.FreeAMMediaType(pSampleGrabber_pmt);
    CheckHR(hr, "Can't set media type to sample grabber.");
}

你会看到我有更多的代码,如连接智能tee和样本抓取器(这不是原因,因为我之前已经注释了它,以检查结果和没有变化,最终我想从视频流抓取静止图像…所以当我准备好了的时候,我就把它放好了。

我认为问题是与颜色转换器dmo,但我不完全确定…确切的图形在graphhedit运行没有任何问题,但代码模式给了我可怕的回放。也许我忘了用dmo的颜色转换器做些什么?还是包装纸?如有任何意见,不胜感激。

谢谢,欢呼。

我没有关于Color Converter DMO的详细信息,但从其他Vista+ DMOs的经验来看-它们不打算在DirectShow中使用。是的,它们仍然是dmo,实现了IMediaObject接口,DMO Wrapper Filter也在那里,但一些小问题正在破坏集成。

如果它不能开箱即用,很可能您将不得不将DMO放入您自己的包装器过滤器中。这肯定是可行的,而且——好消息——它并没有那么复杂。

旧的dmo肯定是在DirectShow中使用股票包装过滤器进行测试的,这就是为什么它们一直在工作,这就是为什么DMO Wrapper Filter在第一位置可用的原因。

最新更新