Winapi 如何将源过滤器连接到编码器DMO?

Winapi 如何将源过滤器连接到编码器DMO?,winapi,video,directshow,wmv,dmo,Winapi,Video,Directshow,Wmv,Dmo,我有一个用于生成无声视频的DirectShow应用程序,它的过滤图是 my video frame generator -> selectable video compressor -> AVI mux -> file writer pFilterGraph->AddSourceFilter(AVI file) -> AVI splitter -> DMO wrapper for WMV -> AVI mux -> file writer 或者

我有一个用于生成无声视频的DirectShow应用程序,它的过滤图是

my video frame generator -> selectable video compressor -> AVI mux -> file writer
pFilterGraph->AddSourceFilter(AVI file) -> AVI splitter -> DMO wrapper for WMV -> AVI mux -> file writer
或者只是

my video frame generator -> AVI mux -> file writer
这通常按预期工作,除非所选压缩器是DMO,在这种情况下,从源到压缩器的pFilterGraph->Connect()调用失败-通常是VFW_E_TYPE_未被接受或VFW_E_无法连接。我想让DMO也起作用。我发现了一个不推荐使用的示例(avinecoderdshow),我可以通过WMV9 DMO对该示例进行调整以压缩输入AVI文件,这在这方面似乎很有希望。它的过滤图是

my video frame generator -> selectable video compressor -> AVI mux -> file writer
pFilterGraph->AddSourceFilter(AVI file) -> AVI splitter -> DMO wrapper for WMV -> AVI mux -> file writer
所以我想我可以把源过滤器换成我的过滤器(或者它所基于的bouncing ball DirectShow示例)。但是,尝试这样做只会导致相同的连接失败。我提供的源代码是32位RGB,WMV9应该接受它。它会在什么地方绊倒

编辑: 我首选的媒体类型的详细信息如下:

majortype: MEDIATYPE_Video
subtype: MEDIASUBTYPE_RGB32
bFixedSizeSamples: 1
bTemporalCompression: 0
lSampleSize: 3145728
formattype: CLSID_KsDataTypeHandlerVideo
pUnk: NULL
cbFormat: 1128
pbFormat: 0x12ce4bf0
不接受VFW_E_类型的确切故障点

hr = pReceivePin->ReceiveConnection((IPin *)this, pmt);
CBasePin::AttemptConnection(IPin * pReceivePin, const CMediaType * pmt) Line 1796   C++
CBasePin::AgreeMediaType(IPin * pReceivePin, const CMediaType * pmt) Line 1939  C++
CBasePin::Connect(IPin * pReceivePin, const _AMMediaType * pmt) Line 1728   C++
CFilterGraph::ConnectDirectInternal(struct IPin *,struct IPin *,struct _AMMediaType const *)    Unknown
CFilterGraph::ConnectDirect(struct IPin *,struct IPin *,struct _AMMediaType const *)    Unknown
ConnectFilters(IBaseFilter * pUpstream, IBaseFilter * pDownstream, IGraphBuilder * pGraph, _AMMediaType * pmt) Line 332 C++
我的媒体类型的pbFormat设置为VIDEOINFO,它似乎与VIDEOINFOHEADER具有相同的结构,但在其末尾附加了额外的数据。看起来是这样的:

rcSource    {LT(0, 0) RB(0, 0)  [0 x 0]}    tagRECT
rcTarget    {LT(0, 0) RB(0, 0)  [0 x 0]}    tagRECT
dwBitRate   0   unsigned long
dwBitErrorRate  0   unsigned long
AvgTimePerFrame 0   __int64
bmiHeader   {biSize=40 biWidth=1024 biHeight=768 ...}   tagBITMAPINFOHEADER
    biSize  40  unsigned long
    biWidth 1024    long
    biHeight    768 long
    biPlanes    1   unsigned short
    biBitCount  32  unsigned short
    biCompression   0   unsigned long
    biSizeImage 3145728 unsigned long
    biXPelsPerMeter 0   long
    biYPelsPerMeter 0   long
    biClrUsed   0   unsigned long
    biClrImportant  0   unsigned long
bmiColors   0x0d381c60 {{rgbBlue=0 '\0' rgbGreen=0 '\0' rgbRed=0 '\0' ...}, {rgbBlue=0 '\0' rgbGreen=0 '\0' rgbRed=...}, ...}   tagRGBQUAD[256]
dwBitMasks  0x0d381c60 {0, 0, 0}    unsigned long[3]
    [0] 0   unsigned long
    [1] 0   unsigned long
    [2] 0   unsigned long
TrueColorInfo   {dwBitMasks=0x0d381c60 {0, 0, 0} bmiColors=0x0d381c6c {{rgbBlue=0 '\0' rgbGreen=0 '\0' rgbRed=0 '\0' ...}, ...} }

一些过滤器,特别是多路复用器,有时是编码器,要求您指定视频流的帧速率。否则,媒体类型将被拒绝,并显示通用错误代码,而不会提及帧速率是原因

WMV9编码器DMO在输入端接受32位RGB,因此您应该在媒体类型的
VIDEOINFOHEADER
结构中使用肯定的
AvgTimePerFrame
值进行尝试:


VFW_E_TYPE_NOT_ACCEPTED
表示该类型不兼容。DMO将只接受某些媒体类型,并且您的源还能够提供特定媒体类型的数据。如果有匹配项,您将成功连接。。。也许你应该发布更多关于你拥有的内容的详细信息(源代码上的媒体类型)。
CLSID\u KsDataTypeHandlerVideo
FORMAT\u VideoInfo
VIDEOINFOHEADER
中有什么内容。我想WMV编码器接受32位RGB。@RomanR:是的,它的值与FORMAT\u VideoInfo相同。我已经在主要问题中添加了信息。我认为您不需要在
VIDEOINFOHEADER
(使cbFormat大到1128)之外添加数据,但这不太可能是个问题。真正可能导致连接失败的是零
AvgTimePerFrame
,我会在那里尝试一个非零值。我只是快速检查了一下-是的,我可以将我的32位RGB源连接到包装好的WMV9 DMO。@RomanR:设置AvgTimePerFrame确实解决了这个问题!非常感谢!如果你想加上这个作为回答,我会接受的。