1

为了在我的 WPF 应用程序中呈现 DirectShow 图形,我使用示例抓取器将位图写入内存,并在代码的其他位置读取它。这似乎是一个奇怪的解决方案,但似乎是从中获得 WPF 画笔的唯一方法。

以下代码为我提供了我需要的有关位图的信息:

AMMediaType mt = grabber.GetConnectedMediaType();
VideoInfoHeader header = (VideoInfoHeader)Marshal.PtrToStructure(mt.formatPtr, typeof VideoInfoHeader);
header.BmiHeader // ...

现在,header.BmiHeaderBitmapInfoHeader类型,并提供位图的宽度高度等信息。我需要这些信息来将位图写入内存。

但是,此代码似乎并不总是有效。例如,当采样采集器过滤器连接到 MPEG-2 节目流引脚时,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在 C++ 中)为 0。

4

1 回答 1

0

如果你想要一个位图,你需要将样本采集器放在你接收未压缩视频的地方。当采样器位于 MPEG-2 节目流引脚后面时,您将收到一个 mpeg2 节目流。当然可以从中得到一个位图,但是你需要手动解复用和解压缩。两者都是您要在 directshow 过滤器中执行的任务。

但即使您收到未压缩的视频,您仍可能会获得不同的格式。根据解码器的不同,您可以接收 RGB24、YUY2、YV12,... 检查 MediaSubType 以了解您收到的内容。如果您总是想接收 RGB24,您可以使用 sdk 中包含的 RGBFilters/TransNull24 过滤器。另请参阅此答案

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

于 2013-01-03T19:53:51.927 回答