C# DirectShow快速播放不稳定的视频
我正在使用DirectShow/VMR9在我的应用程序中播放MPEG 4视频。我使用IMediaSeeking SetRate来设置视频的速度。播放我创建的视频,速度高达4倍,播放效果很好,超过这个速度,视频会变得非常急促。使用Windows media player以4倍以上的速度播放同一文件并非易变。有人能解释一下为什么windows media player可以快速播放我的文件,但我的DirectShow筛选器图形不能 我的图形拓扑是Recording.avi->avi Splitter->Mpeg4s解码器DMO->Ds.NET抓取器->颜色空间转换器->视频混合渲染器9C# DirectShow快速播放不稳定的视频,c#,directshow,C#,Directshow,我正在使用DirectShow/VMR9在我的应用程序中播放MPEG 4视频。我使用IMediaSeeking SetRate来设置视频的速度。播放我创建的视频,速度高达4倍,播放效果很好,超过这个速度,视频会变得非常急促。使用Windows media player以4倍以上的速度播放同一文件并非易变。有人能解释一下为什么windows media player可以快速播放我的文件,但我的DirectShow筛选器图形不能 我的图形拓扑是Recording.avi->avi Splitter-
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的引用