C# DirectShow快速播放不稳定的视频

C# DirectShow快速播放不稳定的视频,c#,directshow,C#,Directshow,我正在使用DirectShow/VMR9在我的应用程序中播放MPEG 4视频。我使用IMediaSeeking SetRate来设置视频的速度。播放我创建的视频,速度高达4倍,播放效果很好,超过这个速度,视频会变得非常急促。使用Windows media player以4倍以上的速度播放同一文件并非易变。有人能解释一下为什么windows media player可以快速播放我的文件,但我的DirectShow筛选器图形不能 我的图形拓扑是Recording.avi->avi Splitter-

我正在使用DirectShow/VMR9在我的应用程序中播放MPEG 4视频。我使用IMediaSeeking SetRate来设置视频的速度。播放我创建的视频,速度高达4倍,播放效果很好,超过这个速度,视频会变得非常急促。使用Windows media player以4倍以上的速度播放同一文件并非易变。有人能解释一下为什么windows media player可以快速播放我的文件,但我的DirectShow筛选器图形不能

我的图形拓扑是Recording.avi->avi Splitter->Mpeg4s解码器DMO->Ds.NET抓取器->颜色空间转换器->视频混合渲染器9

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

        // Set the media type to Video/RBG24
        media = new AMMediaType();
        media.majorType = MediaType.Video;
        media.subType = MediaSubType.ARGB32; // tried NV12 here, gives error.
        media.formatType = FormatType.VideoInfo;
        hr = sampleGrabber.SetMediaType(media);
        DsError.ThrowExceptionForHR(hr);

        DsUtils.FreeAMMediaType(media);
        media = null;

        // Configure the samplegrabber
        hr = sampleGrabber.SetBufferSamples(true);
        DsError.ThrowExceptionForHR(hr);
    }
如果你需要进一步的信息,请告诉我

更新

我卸下了抓取器(因此也卸下了csc),播放速度不会达到8倍,这就足够了,但我确实需要抓取器。当我添加抓取器时,CSC就在那里结束了。如果可能的话,我想移除CSC,看看在保留抓取器的同时是否能改善情况。下面是我的带有中间格式的图表(带和不带过滤器)。我尝试将抓取器的媒体子类型设置为NV12(如非抓取器图形),但出现错误“找不到中间过滤器的组合来建立连接”。我包含了配置抓取器的代码

有没有可能在没有csc的情况下实现这一点

也不确定它是否相关,但我不明白在没有抓取器的情况下,图像上的视频尺寸是如何变化的

带抓取器

Recording.avi-----(avi)---avi拆分器------(MP4V-704*576–24位)---Mpeg4s解码器DMO------(RGB24 704*576)---Ds.NET抓取器-(RGB24 704*576)---颜色空间转换器------视频混合渲染器9

不带抓取器

Recording.avi-----(avi)--avi拆分器------(MP4V-704*576–24位)--Mpeg4s解码器DMO------(NV12 768*576 12位)--视频混合渲染器9

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

        // Set the media type to Video/RBG24
        media = new AMMediaType();
        media.majorType = MediaType.Video;
        media.subType = MediaSubType.ARGB32; // tried NV12 here, gives error.
        media.formatType = FormatType.VideoInfo;
        hr = sampleGrabber.SetMediaType(media);
        DsError.ThrowExceptionForHR(hr);

        DsUtils.FreeAMMediaType(media);
        media = null;

        // Configure the samplegrabber
        hr = sampleGrabber.SetBufferSamples(true);
        DsError.ThrowExceptionForHR(hr);
    }
CPU使用详细信息

核心i3-3300MHz–带超读4GB RAM

4倍速度

CPU1~45%

CPU2~0%

CPU3~33%

CPU4~0%

8倍速度

CPU1~40%

CPU2~25%(但非常尖锐的0-50%)

CPU3~40%

CPU4~0%

核心i3-3300MHz–在BIOS中禁用超读。

4倍速度

CPU1~45%

CPU2~33%

8倍速度(16倍速度下的结果相同)

CPU1~66%


CPU2~45%

一个典型的原因是,在此播放速率下,解码线程以100%的CPU运行,无法解码更多的帧,您开始看到不规则的帧显示和/或帧丢失

在哪里可以看到:

  • 使用任务管理器或其他应用程序检查您的CPU,查看其中一个内核是否已达到最大值,并且不再处于空闲状态
  • 已检查VMR属性,以查看帧是否丢失,或抖动是否变得过高

一个典型的原因是,在这种播放速率下,您的解码线程以100%的CPU运行,无法解码更多的帧,您开始看到不规则的帧显示和/或帧丢失

在哪里可以看到:

  • 使用任务管理器或其他应用程序检查您的CPU,查看其中一个内核是否已达到最大值,并且不再处于空闲状态
  • 已检查VMR属性,以查看帧是否丢失,或抖动是否变得过高

为了播放视频,MediaPlayer正在使用MediaFoundation。对于大多数视频,播放都是硬件加速的。如果在DirectShow中的解码器和渲染器之间有一些过滤器,则DirectShow中没有硬件加速。
请在没有DS.Net抓取器和颜色空间转换器的情况下重试(=>csc也是一个巨大的性能杀手)

用于播放MediaPlayer使用MediaFoundation的视频。对于大多数视频,播放都是硬件加速的。如果在DirectShow中的解码器和渲染器之间有一些过滤器,则DirectShow中没有硬件加速。
请在没有DS.Net抓取器和颜色空间转换器的情况下再试一次(=>csc也是一个巨大的性能杀手)

卸下抓取器可以消除抖动,尽管我确实需要抓取器。如果可能的话,我正在尝试移除csc,请参阅更新的我的第一篇文章。移除抓取器会移除抖动,尽管我确实需要抓取器。如果可能的话,我正在尝试删除csc,请参阅更新后的第一篇文章。CPU负载不是太高,我开始看到在高速播放时抖动和帧下降。移除抓取器似乎确实可以改善情况。抓取器和
CSC
过滤器本身并不是问题所在,它们的开销很小(另一个答案则相反,但并不完全正确)。添加抓取器时遇到的问题是,解码器被迫输出
RGB
视频,而不是格式良好的
NV12
<代码>RGB转换增加了开销,并消耗了更多的硬件带宽-这是对性能的影响。但这正是您设置管道所要做的,因为您希望将
RGB
数据从抓取器复制到应用程序中。无论如何,我仍然怀疑瓶颈是CPU和/或你的抓取回调。我已经把CPU使用细节添加到我原来的文章中了。我不认为它们太高了吗?另外,关于您对回调的评论,我没有使用回调,我正在缓冲帧
sampleGrabber.SetBufferSamples(true)
然后在按下捕获图像按钮时使用
sampleGrabber.GetCurrentBuffer(xx,xx)
。缓冲是一项昂贵的操作-无论您是否实际需要,您都会将每个视频帧复制到缓冲区中。就性能而言,这比回调更糟糕,因为在回调中,您可能只是保留了媒体sam的引用