0

I have a DirectShow app for generating silent videos, whose filter graph is

my video frame generator -> selectable video compressor -> AVI mux -> file writer

or just

my video frame generator -> AVI mux -> file writer

This mostly works as expected, unless the selected compressor is a DMO, in which case the pFilterGraph->Connect() call from source to compressor fails - typically with VFW_E_TYPE_NOT_ACCEPTED or VFW_E_CANNOT_CONNECT. I would like to make DMOs work too. I found a deprecated sample (AVIEncoderDShow) that I was able to tweak to compress an input AVI file with the WMV9 DMO, which seemed promising on this score. Its filter graph is

pFilterGraph->AddSourceFilter(AVI file) -> AVI splitter -> DMO wrapper for WMV -> AVI mux -> file writer

so I thought I could just swap out the source filter for my filter (or the bouncing ball DirectShow sample that it's based on). Trying that just gives the same connection failures though. The source I'm supplying is 32 bit RGB, which WMV9 should accept. What might it be stumbling on?

EDIT: The details of my preferred media type are:

majortype: MEDIATYPE_Video
subtype: MEDIASUBTYPE_RGB32
bFixedSizeSamples: 1
bTemporalCompression: 0
lSampleSize: 3145728
formattype: CLSID_KsDataTypeHandlerVideo
pUnk: NULL
cbFormat: 1128
pbFormat: 0x12ce4bf0

and the exact point of failure with VFW_E_TYPE_NOT_ACCEPTED is

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++

My media type's pbFormat is set up as a VIDEOINFO, which seems to have the same structure as a VIDEOINFOHEADER but with additional data tacked on the end of it. It looks like this:

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' ...}, ...} }
4

1 回答 1

0

某些过滤器,尤其是多路复用器,有时是编码器,要求您指定视频流的帧速率。否则媒体类型会被通用错误代码拒绝,而没有提到帧速率是原因。

WMV9 编码器 DMO 确实在输入上接受 32 位 RGB,因此您应该在媒体类型AvgTimePerFrame的结构中尝试使用正值:VIDEOINFOHEADER

在此处输入图像描述

于 2015-10-23T10:12:15.313 回答