如何将源滤波器连接到编码器 DMO?
How to connect a source filter to an encoder DMO?
我有一个用于生成无声视频的 DirectShow 应用程序,其过滤图是
my video frame generator -> selectable video compressor -> AVI mux -> file writer
或者只是
my video frame generator -> AVI mux -> file writer
这主要按预期工作,除非所选压缩器是 DMO,在这种情况下,从源到压缩器的 pFilterGraph->Connect() 调用失败 - 通常为 VFW_E_TYPE_NOT_ACCEPTED 或 VFW_E_CANNOT_CONNECT。我也想让 DMO 工作。我找到了一个已弃用的示例 (AVIEncoderDShow),我可以调整它以使用 WMV9 DMO 压缩输入的 AVI 文件,这在这个分数上似乎很有希望。它的过滤图是
pFilterGraph->AddSourceFilter(AVI file) -> AVI splitter -> DMO wrapper for WMV -> AVI mux -> file writer
所以我想我可以将源过滤器换成我的过滤器(或它所基于的弹跳球 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_TYPE_NOT_ACCEPTED 的确切故障点是
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 '[=15=]' rgbGreen=0 '[=15=]' rgbRed=0 '[=15=]' ...}, {rgbBlue=0 '[=15=]' rgbGreen=0 '[=15=]' 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 '[=15=]' rgbGreen=0 '[=15=]' rgbRed=0 '[=15=]' ...}, ...} }
一些过滤器,尤其是多路复用器,有时是编码器,需要您指定视频流的帧速率。否则,媒体类型将被拒绝并显示一般错误代码,而不会提及帧速率是原因。
WMV9 编码器 DMO 在输入端接受 32 位 RGB,因此您应该在 VIDEOINFOHEADER
媒体类型结构中使用正 AvgTimePerFrame
值进行尝试:
我有一个用于生成无声视频的 DirectShow 应用程序,其过滤图是
my video frame generator -> selectable video compressor -> AVI mux -> file writer
或者只是
my video frame generator -> AVI mux -> file writer
这主要按预期工作,除非所选压缩器是 DMO,在这种情况下,从源到压缩器的 pFilterGraph->Connect() 调用失败 - 通常为 VFW_E_TYPE_NOT_ACCEPTED 或 VFW_E_CANNOT_CONNECT。我也想让 DMO 工作。我找到了一个已弃用的示例 (AVIEncoderDShow),我可以调整它以使用 WMV9 DMO 压缩输入的 AVI 文件,这在这个分数上似乎很有希望。它的过滤图是
pFilterGraph->AddSourceFilter(AVI file) -> AVI splitter -> DMO wrapper for WMV -> AVI mux -> file writer
所以我想我可以将源过滤器换成我的过滤器(或它所基于的弹跳球 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_TYPE_NOT_ACCEPTED 的确切故障点是
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 '[=15=]' rgbGreen=0 '[=15=]' rgbRed=0 '[=15=]' ...}, {rgbBlue=0 '[=15=]' rgbGreen=0 '[=15=]' 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 '[=15=]' rgbGreen=0 '[=15=]' rgbRed=0 '[=15=]' ...}, ...} }
一些过滤器,尤其是多路复用器,有时是编码器,需要您指定视频流的帧速率。否则,媒体类型将被拒绝并显示一般错误代码,而不会提及帧速率是原因。
WMV9 编码器 DMO 在输入端接受 32 位 RGB,因此您应该在 VIDEOINFOHEADER
媒体类型结构中使用正 AvgTimePerFrame
值进行尝试: