关于在 DirectShowNet 中渲染流的问题

发布于 2024-11-14 11:16:35 字数 3543 浏览 3 评论 0原文

目前我有一个由我的程序创建的损坏的 avi 文件。我发现通过进入 graphedit,我可以正确地重新调整它。

我发现如果我这样做:

SourceFile(test1.avi) -> AVI Splitter -> ffdshow video encoder -> AVI Mux -> File Writer

我可以得到正确的视频流。

现在我正在尝试将其转换为我可以调用的 C# Directshow.Net 程序。

我创建一个图表,然后从要转换的视频文件中添加 SourceFilter,添加抓取器,找到并添加 ffdshow 编码器、AVI Mux,然后添加 setOutputFileName()。

{
        filename = textBox1.Text;
        IFilterGraph2 filter = new FilterGraph() as IFilterGraph2;
        ICaptureGraphBuilder2 MainGraph = new CaptureGraphBuilder2() as ICaptureGraphBuilder2;
        int result;
        result = MainGraph.SetFiltergraph(filter);

        IBaseFilter source;
        result = filter.AddSourceFilter(filename, filename, out source);

        ISampleGrabber samplegrabber = (ISampleGrabber)new SampleGrabber();
        IBaseFilter basegrab = (IBaseFilter)samplegrabber;

        AMMediaType media;
        media = new AMMediaType();
        media.majorType = MediaType.Video;
        media.subType = MediaSubType.RGB32;
        media.formatType = FormatType.VideoInfo;
        result = samplegrabber.SetMediaType(media);

        DsUtils.FreeAMMediaType(media);
        result = samplegrabber.SetBufferSamples(true);

        result = filter.AddFilter(basegrab, "filter");

        //MainGraph.RenderStream(null, null, source, basegrab, null);



        IMediaEvent mediaEvent;
        IMediaControl mediacontrol;
        mediaEvent = filter as IMediaEvent;
        mediacontrol = filter as IMediaControl;






        IntPtr hEvent;
        result = mediaEvent.GetEventHandle(out hEvent);

        ManualResetEvent mre;

        mre = new ManualResetEvent(false);
        mre.SafeWaitHandle = new Microsoft.Win32.SafeHandles.SafeWaitHandle(hEvent, true);

        //Thread t = new Thread(new ThreadStart(this.EventWait));

        //mediacontrol.Run();

        object newsource = null;
        IBaseFilter encoder;

        Guid iid = typeof(IBaseFilter).GUID;
        foreach (DsDevice device in DsDevice.GetDevicesOfCat(FilterCategory.VideoCompressorCategory))
        {
            if (device.Name.CompareTo("ffdshow video encoder") == 0)
            {
                device.Mon.BindToObject(null, null, ref iid, out newsource);
                break;
            }
        }

        encoder = (IBaseFilter)newsource;
object newsource2 = null;
        IBaseFilter encoder2;

        Guid iid2 = typeof(IBaseFilter).GUID;
        foreach (DsDevice device in DsDevice.GetDevicesOfCat(FilterCategory.LegacyAmFilterCategory))
        {
            if (device.Name.CompareTo("AVI Mux") == 0)
            {
                device.Mon.BindToObject(null, null, ref iid2, out newsource2);
                break;
            }
        }

        encoder2 = (IBaseFilter)newsource2;
        result = filter.AddFilter(encoder, "encoder");
        result = filter.AddFilter(encoder2, "Avi Mux");


        FileWriter file = new FileWriter();
        IFileSinkFilter fs = (IFileSinkFilter)file;
        IBaseFilter mux;
        IFileSinkFilter sink;
        Guid cat;
        Guid med;
  cat = PinCategory.Capture;
        med = MediaType.Video;


        //result = filter.AddFilter(encoder, "encoder");
        result = MainGraph.SetOutputFileName(MediaSubType.Avi, "C:\\Users\\Caleb\\Desktop\\conversion.avi", out mux, out sink);

        result = MainGraph.RenderStream( cat,  med, source, null, mux);
mediacontrol.Run();

}

据我所知,这段代码创建了相同的图表。它创建我的文件,但不转换任何内容。它创建的文件是 0 字节。我的渲染流错误还是代码中出现其他错误?

currently I have a disfigured avi file that a program of mine creates. I found out that by going into graphedit, i can refigure it correctly.

I found that if i do:

SourceFile(test1.avi) -> AVI Splitter -> ffdshow video encoder -> AVI Mux -> File Writer

i can get a video stream back that is correct.

Now I am trying to convert this into C# Directshow.Net program that i can just call.

I create a graph and i add in a SourceFilter from the video file i want converted, i add in a grabber, find and then add the ffdshow encoder, AVI Mux and then setOutputFileName().

{
        filename = textBox1.Text;
        IFilterGraph2 filter = new FilterGraph() as IFilterGraph2;
        ICaptureGraphBuilder2 MainGraph = new CaptureGraphBuilder2() as ICaptureGraphBuilder2;
        int result;
        result = MainGraph.SetFiltergraph(filter);

        IBaseFilter source;
        result = filter.AddSourceFilter(filename, filename, out source);

        ISampleGrabber samplegrabber = (ISampleGrabber)new SampleGrabber();
        IBaseFilter basegrab = (IBaseFilter)samplegrabber;

        AMMediaType media;
        media = new AMMediaType();
        media.majorType = MediaType.Video;
        media.subType = MediaSubType.RGB32;
        media.formatType = FormatType.VideoInfo;
        result = samplegrabber.SetMediaType(media);

        DsUtils.FreeAMMediaType(media);
        result = samplegrabber.SetBufferSamples(true);

        result = filter.AddFilter(basegrab, "filter");

        //MainGraph.RenderStream(null, null, source, basegrab, null);



        IMediaEvent mediaEvent;
        IMediaControl mediacontrol;
        mediaEvent = filter as IMediaEvent;
        mediacontrol = filter as IMediaControl;






        IntPtr hEvent;
        result = mediaEvent.GetEventHandle(out hEvent);

        ManualResetEvent mre;

        mre = new ManualResetEvent(false);
        mre.SafeWaitHandle = new Microsoft.Win32.SafeHandles.SafeWaitHandle(hEvent, true);

        //Thread t = new Thread(new ThreadStart(this.EventWait));

        //mediacontrol.Run();

        object newsource = null;
        IBaseFilter encoder;

        Guid iid = typeof(IBaseFilter).GUID;
        foreach (DsDevice device in DsDevice.GetDevicesOfCat(FilterCategory.VideoCompressorCategory))
        {
            if (device.Name.CompareTo("ffdshow video encoder") == 0)
            {
                device.Mon.BindToObject(null, null, ref iid, out newsource);
                break;
            }
        }

        encoder = (IBaseFilter)newsource;
object newsource2 = null;
        IBaseFilter encoder2;

        Guid iid2 = typeof(IBaseFilter).GUID;
        foreach (DsDevice device in DsDevice.GetDevicesOfCat(FilterCategory.LegacyAmFilterCategory))
        {
            if (device.Name.CompareTo("AVI Mux") == 0)
            {
                device.Mon.BindToObject(null, null, ref iid2, out newsource2);
                break;
            }
        }

        encoder2 = (IBaseFilter)newsource2;
        result = filter.AddFilter(encoder, "encoder");
        result = filter.AddFilter(encoder2, "Avi Mux");


        FileWriter file = new FileWriter();
        IFileSinkFilter fs = (IFileSinkFilter)file;
        IBaseFilter mux;
        IFileSinkFilter sink;
        Guid cat;
        Guid med;
  cat = PinCategory.Capture;
        med = MediaType.Video;


        //result = filter.AddFilter(encoder, "encoder");
        result = MainGraph.SetOutputFileName(MediaSubType.Avi, "C:\\Users\\Caleb\\Desktop\\conversion.avi", out mux, out sink);

        result = MainGraph.RenderStream( cat,  med, source, null, mux);
mediacontrol.Run();

}

this code creates the same graph to my knowledge. It creates my file, but doesnt convert anything. The file it creates is 0bytes. Am i doing renderstream wrong or some other error in my code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仅一夜美梦 2024-11-21 11:16:35

我输入了一段代码:

DsRotEntry m_rot = new DsRotEntry(filter);

这使我可以在 graphedit 中查看我制作的过滤器。

发生的情况是我添加了过滤器,但它们都没有相互连接。

然后我所做的就是获取我添加的每个滤波器,找到与它们关联的输入和输出引脚,

Filter2.FindPin( "name of the input pin here", out pinName);
Filter1.FindPin( "name of the output pin here", out PinName2);

MainFilter.connect( PinName2, pinName);

这在滤波器之间创建了连接。我没有这样做,但我这样做了,现在我越来越接近我想要的了。

所以基本上对于 Directshow.net 和 DirectShowNet-Lib 它的程序如下

find a filter -> add a filter -> find a filter -> add a filter -> find the pins -> connect the pins -> run

i put in a piece of code:

DsRotEntry m_rot = new DsRotEntry(filter);

this allowed me to view my filter i made, in graphedit.

what happened was i add the filters but none of them got connected to each other.

So then what i did was got each of the filters i added, found the input and output pins associated with them

Filter2.FindPin( "name of the input pin here", out pinName);
Filter1.FindPin( "name of the output pin here", out PinName2);

MainFilter.connect( PinName2, pinName);

this created a connection between the filters. I wasnt doing this and i did this and now im getting closer to what i want.

so basically for Directshow.net and DirectShowNet-Lib it programs like

find a filter -> add a filter -> find a filter -> add a filter -> find the pins -> connect the pins -> run
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文