Filtergraph生成空文件 我试图用C++来构造一个在Clinux中创建的工作滤波器。

Filtergraph生成空文件 我试图用C++来构造一个在Clinux中创建的工作滤波器。,c++,directshow,C++,Directshow,这是过滤器图: 这是我的代码,它生成一个空的输出文件 #include <dshow.h> #include "MyFilter.h" IPin *GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir) { BOOL bFound = FALSE; IEnumPins *pEnum; IPin *pPin; pFilter->EnumPins(&pEnum);

这是过滤器图:

这是我的代码,它生成一个空的输出文件

#include <dshow.h>
#include "MyFilter.h"

IPin *GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir)
{
    BOOL       bFound = FALSE;
    IEnumPins  *pEnum;
    IPin       *pPin;

    pFilter->EnumPins(&pEnum);
    while (pEnum->Next(1, &pPin, 0) == S_OK)
    {
        PIN_DIRECTION PinDirThis;
        pPin->QueryDirection(&PinDirThis);
        if (bFound = (PinDir == PinDirThis))
            break;
        pPin->Release();
    }
    pEnum->Release();
    return (bFound ? pPin : 0);
}
int CALLBACK WinMain(
    _In_  HINSTANCE hInstance,
    _In_  HINSTANCE hPrevInstance,
    _In_  LPSTR lpCmdLine,
    _In_  int nCmdShow
    )
{
    //INIT GRAPH
    CoInitialize(NULL);

    IGraphBuilder* graphBuilder = NULL;
    IMediaControl* mediaControl = NULL;
    IMediaEvent* mediaEvent = NULL;

    HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IFilterGraph, (void **)&graphBuilder);

    graphBuilder->QueryInterface(IID_IMediaControl, (void **)&mediaControl);
    graphBuilder->QueryInterface(IID_IMediaEvent, (void **)&mediaEvent);


    //SOURCE FILTER
    IBaseFilter* pSource;

    graphBuilder->AddSourceFilter(L"C:\\TEMP\\Zim.avi", NULL, &pSource);


    IPin* sourceOUT = GetPin(pSource, PINDIR_OUTPUT);

    //AVI SPLITTER

    IBaseFilter* aviSplitter = NULL;

    hr = CoCreateInstance(CLSID_AviSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&aviSplitter);

    IPin* aviSplitIN = GetPin(aviSplitter, PINDIR_INPUT);
    IPin* aviSplitOUT = GetPin(aviSplitter, PINDIR_OUTPUT);

    graphBuilder->AddFilter(aviSplitter, L"AVI_SPLITTER");

    graphBuilder->Connect(sourceOUT, aviSplitIN);

    //AVI MUX

    IBaseFilter* decompressor = NULL;
    hr = CoCreateInstance(CLSID_AviDest, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&decompressor);
    graphBuilder->AddFilter(decompressor, L"Decoder");

    IPin* decoderIN = GetPin(decompressor, PINDIR_INPUT);
    IPin* DecoderOUT = GetPin(decompressor, PINDIR_OUTPUT);

    graphBuilder->Connect(aviSplitOUT, decoderIN);

    //File Writer
    IBaseFilter *filewriter = NULL;
    IFileSinkFilter* filesink = NULL;

    hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&filewriter);

    filewriter->QueryInterface(IID_IFileSinkFilter, (void **)&filesink);
    graphBuilder->AddFilter(filewriter, L"Filewriter");
    IPin* filewriterIN = GetPin(filewriter, PINDIR_INPUT);
    graphBuilder->Connect(DecoderOUT, filewriterIN);

    filesink->SetFileName(L"C:\\TEMP\\myfilteroutput123.avi", NULL);

    hr = mediaControl->Run();
    if (SUCCEEDED(hr))
    {
        long evCode;
        mediaEvent->WaitForCompletion(INFINITE, &evCode);
    }

    CoUninitialize();

}
#包括
#包括“MyFilter.h”
IPin*GetPin(IBaseFilter*pFilter,PIN_方向PinDir)
{
boolbfound=FALSE;
IEnumPins*pEnum;
IPin*pPin;
pFilter->EnumPins和pEnum;
而(pEnum->Next(1,&pPin,0)=S_OK)
{
PIN_方向PinDirThis;
pPin->QueryDirection(&PinDirThis);
if(bFound=(PinDir==PinDirThis))
打破
pPin->Release();
}
pEnum->Release();
返回(b发现?pPin:0);
}
int回调WinMain(
_在uhinstance中,
_在此情况下,
_在LPSTR lpCmdLine中,
_In_uuint nCmdShow
)
{
//初始图
共初始化(空);
IGraphBuilder*graphBuilder=NULL;
IMediaControl*mediaControl=NULL;
IMediaEvent*mediaEvent=NULL;
HRESULT hr=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_服务器,IID_IFilterGraph,(void**)和graphBuilder);
graphBuilder->QueryInterface(IID_IMediaControl,(void**)和mediaControl);
graphBuilder->QueryInterface(IID_IMediaEvent,(void**)和mediaEvent);
//源过滤器
IBaseFilter*pSource;
graphBuilder->AddSourceFilter(L“C:\\TEMP\\Zim.avi”、NULL和pSource);
IPin*sourceOUT=GetPin(pSource,PINDIR_输出);
//AVI分离器
IBaseFilter*aviSplitter=NULL;
hr=CoCreateInstance(CLSID_AviSplitter,NULL,CLSCTX_INPROC_服务器,IID_IBaseFilter,(void**)和AviSplitter);
IPin*aviSplitIN=GetPin(aviSplitter,PINDIR_输入);
IPin*aviSplitOUT=GetPin(aviSplitter,PINDIR_输出);
graphBuilder->AddFilter(AVI拆分器,L“AVI_拆分器”);
graphBuilder->Connect(sourceOUT、aviSplitIN);
//AVI多路复用器
IBaseFilter*解压器=NULL;
hr=CoCreateInstance(CLSID_AviDest,NULL,CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**)和解压缩器);
graphBuilder->AddFilter(解压器,L“解码器”);
IPin*decoderIN=GetPin(解压器,PINDIR_输入);
IPin*DecoderOUT=GetPin(解压器,PINDIR_输出);
graphBuilder->Connect(avisplotout,decoderIN);
//文件编写器
IBaseFilter*filewriter=NULL;
IFileSinkFilter*filesink=NULL;
hr=CoCreateInstance(CLSID\u FileWriter,NULL,CLSCTX\u INPROC\u服务器,IID\u IBaseFilter,(void**)和FileWriter);
filewriter->QueryInterface(IID_IFileSinkFilter,(void**)和filesink);
graphBuilder->AddFilter(filewriter,L“filewriter”);
IPin*filewriterIN=GetPin(filewriter,PINDIR\u输入);
graphBuilder->Connect(解码路由、文件写入);
filesink->SetFileName(L“C:\\TEMP\\myfilteroutput123.avi”,NULL);
hr=mediaControl->Run();
如果(成功(hr))
{
长EV码;
mediaEvent->WaitForCompletion(无限,&evCode);
}
coninitialize();
}

编辑:问题似乎是avisplitter只返回一个管脚(输入管脚)。但是我不知道为什么或者如何添加输出管脚。

我已经有一段时间没有做DirectShow了,但我似乎记得在连接至少一个输入管脚之前,AVI拆分器没有输出管脚

因此,请尝试执行以下操作:

IPin* aviSplitIN = GetPin(aviSplitter, PINDIR_INPUT);

graphBuilder->AddFilter(aviSplitter, L"AVI_SPLITTER");
graphBuilder->Connect(sourceOUT, aviSplitIN);

IPin* aviSplitOUT = GetPin(aviSplitter, PINDIR_OUTPUT);
我很肯定这会像预期的那样起作用


作为进一步说明,始终获取并检查
HRESULT
s。从
Connect
返回的
HRESULT
将告诉您许多有关您所遇到错误的信息。在传递空pin码的情况下,您将得到一个
E_指针
错误,这可以帮助您更快地将其锁定

您的代码不会添加AVI多路复用器,也不会生成所需的图形。您还应该检查返回的值,因为最后一次
Connect
可能会导致失败。