directshow应用程序中的去隔行滤波器

时间:2013-08-06 22:36:20

标签: c++ windows filter linker directshow

我正在尝试从捕获卡中捕获视频,并在窗口中显示反向隔行扫描。

我正在使用Dscaler的Deinterlace过滤器(http://deinterlace.sourceforge.net/Filter.htm)。我通过

注册了过滤器(Deinterlace.ax)
regsvr32.exe Deinterlace.ax

然后我尝试修改Microsoft的Directshow示例中的“playcap”。我拿了Deinterlace的源代码并复制了“Deinterlace.h”(包含过滤器的定义)并将其放在项目中。

在CaptureVideo函数中,我尝试使用QueryInterface过滤器。

CComPtr<IBaseFilter> pDeinterlace;
hr = g_pGraph->QueryInterface(IID_IDeinterlace, (LPVOID *) &pDeinterlace);
if (FAILED(hr)) {
    return hr;
}

编译时,我收到链接错误:

error LNK1120: 1 unresolved externals
error LNK2001: unresolved external symbol _IID_IDeinterlace

这些是我的包括:

#include <windows.h>
#include <atlbase.h>
#include <dshow.h>
#include <stdio.h>
#include <strsafe.h>
#include <streams.h>
#include <comdef.h>
#include <iostream>

#include "Deinterlace.h"

对于库和目录,我只包括了Directshow。如果没有Deinterlace过滤器代码,程序编译就可以了。

我不确定如何正确包含过滤器(因为我没有可以找到的教程)。我不确定在哪里放置Deinterlace.ax文件(或将其重命名为Deinterlace.dll?)。

提前致谢!

修改

上面由Roman R解决,将Deinterlace_i.c添加到项目中。

我有另一个问题。我是Directshow的新手,我理解基础知识,但是我无法成功查询接口,并将去隔行过滤器附加到图的其余部分。

理想情况下,我想:

Source Capture (preview) -> Deinterlace Filter -> Video Render

我试图从图中查询界面,但我没有运气,它会失败:

hr = g_pGraph->QueryInterface(IID_IDeinterlace, (LPVOID*) &g_pDeinterlace);
if(FAILED(hr)) {    // Fails here
    Msg(TEXT("Failed"));
    return hr;
}

hr = g_pGraph->AddFilter((IBaseFilter*)g_pDeinterlace, L"Deinterlace");
if(FAILED(hr)) {
    Msg(TEXT("Failed in adding filter"));
    return hr;
}

g_pDeinterlace->put_IsOddFieldFirst(VARIANT_FALSE);

不知何故,我需要它来连接来自源的引脚

// somehow pSrcFilter connects to pDeinterlace

hr = g_pCapture->RenderStream (&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
            g_pDeinterlace, NULL, NULL);

我可以在GraphEdit中完成所有工作,但编写代码是c

1 个答案:

答案 0 :(得分:0)

  1. 包括Deinterlace.h是不够的。另外还包括Deinterlace_i.c - 由deinterlacer的IDL生成的另一个文件

  2. DScaler无法连接到Preview输出引脚。它需要媒体样本(帧)上的时间戳,只有Capture引脚可用。用户捕获输出分支,而不是预览。

  3. DScaler代码:

    HRESULT CDeinterlaceFilter::Deinterlace(IMediaSample* pSource)
    {
        CAutoLock l(&m_DeinterlaceLock);
        // ...
        // Get the input stream times
        if(FAILED(pSource->GetTime(&rtStart,&rtStop)))
        {
            return E_FAIL;