我有一个 C# 应用程序,它应该构建一个 DirectShow 图来呈现 H.264 编码的视频流。我使用 DirectShowLib 作为托管包装器。我已经让它与 RTSP 源和 H.264(视频处理项目、DivX、Datastead 等)的不同过滤器一起使用,但最近,我遇到了这里提到的 MontiVision 过滤器。我在 GraphStudio 中试用了它们,并且对它们的性能非常满意,因此我想在我的应用程序中使用它们。
奇怪的是,虽然“MV 流源”和“MV 视频解码器”过滤器在 GraphStudio 中无缝连接(在设置 RTSP URL 之后),但当我在 C# 中尝试相同的事情时,我在尝试连接时得到 VFW_E_NO_ACCEPTABLE_TYPES 的 HRESULT相同的过滤器。“MV Stream Source”输出一个AVC1 Mediatype,我不知道“MV Video Decoder”接受什么媒体类型,但是当我在GraphStudio中连接过滤器时,它似乎接受了AVC1。
我确信引脚名称和 GUID 是正确的(与 GraphStudio 中的相同)。我还尝试在过滤器创建和连接之间等待(Thread.Sleep)长达 10 秒,但无济于事。
有人知道我可能做错了什么吗?谢谢!
连接过滤器的代码如下所示:
int hr = 0;
//add Source Filter
hr = pGraph.AddFilter(pSourceFilter, "Source Filter");
DsHelper.checkHR(hr, "Can't add Source Filter to graph");
//set source filename
IFileSourceFilter pVideoSourceFilter_src = pSourceFilter as IFileSourceFilter;
if (pVideoSourceFilter_src == null)
DsHelper.checkHR(unchecked((int)0x80004002), "Can't get IFileSourceFilter");
hr = pVideoSourceFilter_src.Load(srcFile, null);
DsHelper.checkHR(hr, "Can't load file");
//add Video Decoder
hr = pGraph.AddFilter(pVideoDecoder, "Video Decoder");
DsHelper.checkHR(hr, "Can't add Video Decoder to graph");
//add Video Renderer
IBaseFilter pVideoRenderer = DsHelper.FilterFromGUID(DsHelper.CLSID_NullRenderer);
hr = pGraph.AddFilter(pVideoRenderer, "Video Renderer");
DsHelper.checkHR(hr, "Can't add Video Renderer to graph");
//connect Source Filter and Video Decoder
hr = pGraph.ConnectDirect(DsHelper.GetPin(pSourceFilter, srcFilterVideoOutName), DsHelper.GetPin(pVideoDecoder, vdVideoInName), null);
DsHelper.checkHR(hr, "Can't connect Source Filter and Video Decoder");
创建过滤器:
IBaseFilter pSourceFilter = (IBaseFilter)DsHelper.FilterFromGUID(DsHelper.CLSID_MVRTSPSourceFilter);
IBaseFilter pVideoDecoder = (IBaseFilter)DsHelper.FilterFromGUID(DsHelper.CLSID_MVDecoder);
帮手:
public static Guid CLSID_MVDecoder = new Guid("{D8F0E4C9-38DB-40E7-93C3-248A22D587B8}");
public static Guid CLSID_MVRTSPSourceFilter = new Guid("{EDE234EC-157E-4516-9AC5-0F401384918B}");
public static IBaseFilter FilterFromGUID(Guid filterGuid)
{
return (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(filterGuid));
}
public static IPin GetPin(IBaseFilter filter, string pinname)
{
IEnumPins epins;
int hr = filter.EnumPins(out epins);
checkHR(hr, "Can't enumerate pins");
IntPtr fetched = Marshal.AllocCoTaskMem(4);
IPin[] pins = new IPin[1];
while (epins.Next(1, pins, fetched) == 0)
{
PinInfo pinfo;
pins[0].QueryPinInfo(out pinfo);
bool found = (pinfo.name == pinname);
DsUtils.FreePinInfo(pinfo);
if (found) return pins[0];
}
checkHR(-1, "Pin not found: " + pinname);
return null;
}