从MPEG-2节目/传输流中获取位图信息?

时间:2013-01-03 15:06:03

标签: bitmap marshalling directshow directshow.net

为了在我的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。

1 个答案:

答案 0 :(得分:0)

如果需要位图,则需要将样本抓取器放置在接收未压缩视频的位置。当samplegrabber位于MPEG-2 Program Stream引脚后面时,您将收到一个mpeg2程序流。当然可以从中获取位图,但是您需要手动解复用和解压缩。两者都是您要在directshow过滤器中执行的任务。

但即使您收到未压缩的视频,您仍可能会获得不同的格式。根据解码器,您可以接收RGB24,YUY2,YV12,...检查MediaSubType以获得您的确切接收。如果您总是希望接收RGB24,则可以使用sdk中包含的RGBFilters / TransNull24过滤器。另请参阅this answer

编辑:还有一个注意事项,如果您不仅需要分辨率,还需要位图本身,则必须将samplegrabber放在解码器和渲染器之间。如果MS解码器无法正常工作,请尝试ffdshow