为了在我的WPF应用程序中呈现DirectShow图形,我使用样本抓取器将位图写入内存,并在代码中的其他地方读取它。这似乎是一个奇怪的解决方案,但似乎是让WPF刷出来的唯一方法。
以下代码为我提供了有关位图的信息:
AMMediaType mt = grabber.GetConnectedMediaType();
VideoInfoHeader header = (VideoInfoHeader)Marshal.PtrToStructure(mt.formatPtr, typeof VideoInfoHeader);
header.BmiHeader // ...
现在,header.BmiHeader
的类型为BitmapInfoHeader,并提供位图的宽度和高度等信息。我需要这些信息来将位图写入内存。
但是,此代码似乎并不总是有效。例如,当样本采集过滤器连接到MPEG-2 Program Stream引脚时,header
将为null
。为什么我的代码不适用于某些媒体类型,以及有什么其他方法可以获得它的BitmapInfoHeader结构?
请注意,即使我使用directshow.net库,也欢迎使用C ++中的答案。
修改:这就是我的图表的样子:
*source* -> MPEG2-Demultiplexer -> SampleGrabber -> MS DTV-DVD Video Decoder -> Video Renderer
我不允许将抓取器放在解码器和渲染器之间。关于demux的视频引脚:
Major Type: Video
Sub Type: MPEG2_VIDEO
Format: MPEG2Video
连接样品采集器后,它的输入引脚也具有上述介质类型。当我在我的应用程序中打开此图形文件并使用grabber.GetConnectedMediaType();
时,我也获得了相同的媒体类型。但是,此媒体类型的formatPtr
或(pbFormat
)为0。
答案 0 :(得分:0)
如果需要位图,则需要将样本抓取器放置在接收未压缩视频的位置。当samplegrabber位于MPEG-2 Program Stream引脚后面时,您将收到一个mpeg2程序流。当然可以从中获取位图,但是您需要手动解复用和解压缩。两者都是您要在directshow过滤器中执行的任务。
但即使您收到未压缩的视频,您仍可能会获得不同的格式。根据解码器,您可以接收RGB24,YUY2,YV12,...检查MediaSubType以获得您的确切接收。如果您总是希望接收RGB24,则可以使用sdk中包含的RGBFilters / TransNull24过滤器。另请参阅this answer。
编辑:还有一个注意事项,如果您不仅需要分辨率,还需要位图本身,则必须将samplegrabber放在解码器和渲染器之间。如果MS解码器无法正常工作,请尝试ffdshow。