DirectShow cast sampleGrabber到ISampleGrabber [英] DirectShow cast sampleGrabber to ISampleGrabber

查看:296
本文介绍了DirectShow cast sampleGrabber到ISampleGrabber的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个奇怪的错误,我无法包装我的头。我有一个图形创建在一个单独的线程运行,我试图访问 IBaseFilter sampleGrabber 在控制台应用程序中工作的线程外,但我将代码移动到新项目,并且我试图将 sampleGrabber 转换为 ISampleGrabber ,运行时会引发空引用异常。如果我调试 sampleGrabber 它有接口 ISampleGrabber ,但是我不能再转换它。在运行图形的线程中移动代码使我可以投射它,但它不是我的应用程序的理想。



如何抛出空引用异常, sampleGrabber 到 ISampleGrabber 失败?

解决方案

问题是DirectShow过滤器是早期COM类,在引用计数,接口,标记,持久性的一部分实现COM的一个子集 - 基本上所有好东西都持续了多年 - 然而他们完全忽视公寓。 DirectShow本身是多线程的,通常有一个控制线程,并且有工作线程流线程。 DirectShow概念假设你可以轻松地在线程之间传递接口指针,并且不涉及预期和需要的处理。



然后.NET检查COM包装器,DirectShow.NET包装接口指针,就好像它们是功能齐全的公寓感知的COM指针。同时微软停止给DirectShow更新(例如为Sample Grabber提供免费的线程化封送器),最终你在.NET上遇到这个问题,你不能用接口指针做一个简单的事情。



在本地代码域中使用API​​仍然没有问题,因为您可以跳过封送处理并使用直接指针。



你在一个公寓上构建图形,然后你从另一个公寓的Sample Grabber中调用回来(否则,在你的场景中,你只需在工作线程上做一些事情)。您不能使用原始界面指针,尤其是。那些在成员变量,因为.NET运行时检查将打破公寓不匹配,esp,尝试编组另一个公寓的接口指针。



如果是您的自定义过滤器与源代码,您可以添加自定义 IMarshal 实现或使用免费线程封送器来修复本机代码端的.NET问题,或者添加一个帮助器来跨公寓传递指针。



在.NET代码域中,最好的方法是避免使用多个公寓的指针。可能有选择,但最简单的一个,我想我的头顶是




  • 在MTA工作,以便能够多个线程访问DirectShow接口指针

  • 使用 CLSID_FilterGraphNoThread 版本的Filter Graph Manager

  • 初始化和终止过滤器图


  • 也就是说,使用STA并且没有额外的线程触摸指针,或者其他线程不使用STA。


    I have a strange error that I cannot wrap my head around. I have a graph created in a separate thread that runs and I'm trying to access the IBaseFilter sampleGrabber outside the thread which worked in a console application but I moved the code to a new project and where I'm trying to cast sampleGrabber to ISampleGrabber the runtime complains with a null reference exception. If I debug sampleGrabber it does have the interface ISampleGrabber however I cannot cast it anymore. Moving the code inside the thread running the graph allows me to cast it but its not ideal for my application.

    How can a null reference exception appear by casting what clearly is a sampleGrabber to ISampleGrabber fail?

    解决方案

    The problem is that DirectShow filters are early COM classes that implement a subset of COM in part of reference counting, interfaces, monikers, persistence - basically all good things lasted for years - however they ignore apartments completely. DirectShow is multithreaded on its own and it is typical that there is a controlling thread, and there are worker streaming threads aside. DirectShow concepts assume you can easily pass interface pointers between threads and no marshaling is involved, expected and required.

    Then came .NET with checking COM wrappers, and DirectShow.NET wrapped interface pointers as if they were fully featured apartment-aware COM pointers. At the same time Microsoft stopped giving updates to DirectShow (such as for example supplying Sample Grabber with free threaded marshaler) and eventually you hit the issue when on .NET you cannot do a supposedly simple thing with the interface pointer.

    There is still absolutely no problem working with APIs in native code domain because you can skip marshaling there and work with direct pointers.

    You build the graph on one apartment, and then you get a call back from Sample Grabber on another apartment (or, otherwise, in your scenario you just do something on a worker thread). You cannot use original interface pointers, esp. those in member variables, because .NET runtime check would hit apartment mismatch, esp, trying to marshal interface pointer for another apartment.

    If it were your custom filter with source code, you could have added a custom IMarshal implementation or leverage free threaded marshaler to fix the .NET issue on native code side, or otherwise add a helper to pass pointers across apartments.

    In .NET code domain the best approach would be to avoid working with pointers from multiple apartments. There possibly are choices, but the easiest one I think of off the top of my head is to

    • work in MTA to be able to have multiple threads accessing DirectShow interface pointers
    • use CLSID_FilterGraphNoThread version of Filter Graph Manager
    • initialize and terminate filter graph on a dedicated thread, which during graph operation dispatches window messages

    That is, either use STA and no extra threads touching pointers, or otherwise not use STA.

    这篇关于DirectShow cast sampleGrabber到ISampleGrabber的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆