我尝试编写一个能够在VS2012项目中捕获基于VIDEOINFO2
的流的DirectShow渲染器。为此,我从Windows 7 SDK中获取了基类项目,将其升级到VS2012并构建它。我的渲染器看起来像
class CapturingVideoRenderer : public CBaseVideoRenderer {
public:
CapturingVideoRenderer(LPUNKNOWN pUnk, HRESULT *phr);
virtual ~CapturingVideoRenderer(void);
virtual HRESULT CheckMediaType(const CMediaType *pmt);
virtual HRESULT DoRenderSample(IMediaSample *pMediaSample);
virtual HRESULT SetMediaType(const CMediaType *pmt);
virtual HRESULT StartStreaming(void);
protected:
typedef CBaseVideoRenderer Base;
public:
DECLARE_IUNKNOWN;
};
从实现中,重要的部分是构造函数:
CapturingVideoRenderer::CapturingVideoRenderer(LPUNKNOWN pUnk, HRESULT *phr)
: Base(::CLSID_CapturingVideoRenderer, Name_CapturingVideoRenderer,
pUnk, phr) {
}
如果我现在创建一个实例(我直接进行调试),应用程序崩溃:
IBaseFilter *filter = nullptr;
CapturingVideoRenderer *renderer = nullptr;
HRESULT hr = S_OK;
obj = new CapturingVideoRenderer(nullptr, &hr);
if (FAILED(hr)) { [...] }
//hr = obj->NonDelegatingQueryInterface(IID_IBaseFilter,
// reinterpret_cast<void **>(&filter));
hr = obj->QueryInterface(IID_IBaseFilter,
reinterpret_cast<void **>(&filter));
if (FAILED(hr)) { [...] }
问题似乎是当最后一个基本ctor和我的ctor之间的代码被执行时,vtable(或更多)会以某种方式被破坏。如果我直接调用NonDelegatingQueryInterface
(注释掉),它可以工作(但稍后崩溃),但是对QueryInterface
的调用崩溃,因为它从CUnkown
基类获得实际实现,这是损坏。
虽然我对汇编语言知之甚少,但我还是逐步完成了反汇编。在输入我的ctor的主体之前,执行以下指令,这些指令覆盖位于rax + 18h的基类(CUnknown
)参考计数器的一部分以及基础的其他字段类):
000000013FCBABEF mov rax,qword ptr [this]
000000014000AC07 lea rcx,[CapturingVideoRenderer::`vftable' (0140147A28h)]
000000014000AC0E mov qword ptr [rax+18h],rcx
000000013FCBAC02 mov rax,qword ptr [this]
000000013FCBAC0A lea rcx,[CapturingVideoRenderer::`vftable' (013FDF7A38h)]
000000013FCBAC11 mov qword ptr [rax+20h],rcx
000000013FCBAC15 mov rax,qword ptr [this]
我已经运行了VS2012的静态代码分析,但它没有找到任何有用的东西(来自Windows SDK的基类库中的一些错误的SAL注释)。
最重要的问题当然是:我该如何解决这个问题?
我的其他问题是:在VS2012中使用DirectShow基类是否存在任何已知问题?有可能吗?我是否必须更改一些编译器设置(atm,一切都与项目中的可执行文件相同,它基本上直接来自向导 - 平台工具集v110和Unicode)?
答案 0 :(得分:0)
似乎你无法以这种方式调试DirectShow过滤器。如果我注册它通常&#34;它工作正常,所以COM似乎在这里做了一些重要的事情......