C#.NET DirectShow Lib:将自定义图表保存到文件中

时间:2014-12-03 14:09:36

标签: c# .net graph directshow

我试图在Directshow.net Lib的帮助下在C#.NET中创建一个自定义(Directshow)过滤器图。 lib基于Microsoft的C ++ directshow接口。

创建图表有效,我可以添加一个或多个过滤器。但是,在尝试将图形保存到文件时,它会写入一些字节,但图形编辑器(graphedt.exe)无法打开它。

        DsDevice[] videoInputDevices =
            DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);

        IGraphBuilder graphBuilder = (IGraphBuilder) new FilterGraph();

        ICaptureGraphBuilder2 captureGraphBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2();
        captureGraphBuilder.SetFiltergraph(graphBuilder);

        object source;
        videoInputDevices[0].Mon.BindToObject(
            null,
            null,
            typeof(IBaseFilter).GUID,
            out source);

        IBaseFilter filter = (IBaseFilter)source;
        graphBuilder.AddFilter(filter, "Video Capture");

        try
        {
            int renderStreamComResult = captureGraphBuilder.RenderStream(
                PinCategory.Preview,
                MediaType.Video,
                filter,
                null,
                null);

            MyStreamWriter r = new MyStreamWriter();
            IPersistStream p = (IPersistStream)graphBuilder;

            p.Save(r, true);

            // ugly, only temporary...
            r.bWriter.Flush();
            r.bWriter.Close();
            //


            //DsError.ThrowExceptionForHR(renderStreamComResult);
        }
        finally
        {
            if (filter != null)
            {
                Marshal.ReleaseComObject(filter);
            }

            if (graphBuilder != null)
            {
                Marshal.ReleaseComObject(graphBuilder);
            }

            if (captureGraphBuilder != null)
            {
                Marshal.ReleaseComObject(captureGraphBuilder);
            }
        }

如果我将我生成的文件的内容与我在编辑器中手动创建的文件的内容进行比较,它们看起来会有所不同。

Graph from c# net

Graph made using the editor

实现ComTypes.IStream的MyStreamWriter类:

IPersistStream.Save()仅在编写器上调用Seek()和Write()。

public class MyStreamWriter : IStream
{
    public BinaryWriter bWriter;

    public MyStreamWriter()
    {
        this.bWriter = new BinaryWriter(
            File.OpenWrite("graph.grf"), 
            Encoding.UTF8);
    }

    public void Clone(out iop.ComTypes.IStream ppstm)
    {
        throw new NotImplementedException();
    }

    public void Commit(int grfCommitFlags)
    {
        bWriter.Flush();
        throw new NotImplementedException();
    }

    public void CopyTo(iop.ComTypes.IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten)
    {
        throw new NotImplementedException();
    }

    public void LockRegion(long libOffset, long cb, int dwLockType)
    {
        throw new NotImplementedException();
    }

    public void Read(byte[] pv, int cb, IntPtr pcbRead)
    {
        throw new NotImplementedException();
    }

    public void Revert()
    {
        throw new NotImplementedException();
    }

    public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition)
    {
        bWriter.Seek((int)dlibMove, (SeekOrigin)dwOrigin);
    }

    public void SetSize(long libNewSize)
    {
        throw new NotImplementedException();
    }

    public void Stat(out iop.ComTypes.STATSTG pstatstg, int grfStatFlag)
    {
        throw new NotImplementedException();
    }

    public void UnlockRegion(long libOffset, long cb, int dwLockType)
    {
        throw new NotImplementedException();
    }

    public void Write(byte[] pv, int cb, IntPtr pcbWritten)
    {
        bWriter.Write(pv);
    }
}

directshow lib在IPersistStream中没有做任何奇怪的事情,它只是让C ++接口可用......所以问题必须在其他地方。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

我认为解决方案要简单得多 CSharp DirectShow lib允许您将图形保存在文件中。

此代码适用于我:

使用DirectShowLib.Utils;

FilterGraphTools.SaveGraphFile(this.m_TheGraphBuilder,FilePath);