0

I'm trying to connect a custom source filter to x264. I can connect it to leadtools encoder, main concepts encoder. I can connect them directly in graphedit. I get the HR result 0x80040207 VFW_E_NO_ACCEPTABLE_TYPES.

HRESULT CStreaming::Init(){
    CoInitialize(NULL);
    HRESULT hr;
    hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&m_pGraph));
#ifdef _DEBUG
    DWORD dwRegister;
    hr = AddToRot(m_pGraph, &dwRegister);
#endif
    A_CheckResult(hr);
    IBaseFilter* pSource;
    IBaseFilter* pEncoder;
    IBaseFilter* pColorSpaceConverter;
    IBaseFilter* pTransport;
    FILTER_INFO pfi;

    /* Source Filter*/
    hr = InitFilter(StreamingFilterGUID, &pSource);
    A_CheckResult(hr);
    hr = pSource->QueryFilterInfo(&pfi);
    A_CheckResult(hr);
    hr = m_pGraph->AddFilter(pSource, pfi.achName);
    A_CheckResult(hr);

    hr = InitFilter(x264EncodeGUID, &pEncoder);  
    A_CheckResult(hr);
    hr = pEncoder->QueryFilterInfo(&pfi);
    A_CheckResult(hr);
    hr = m_pGraph->AddFilter(pEncoder, pfi.achName);
    A_CheckResult(hr);
    ...
    /* Queryt Control and Events */
    hr = m_pGraph->QueryInterface(IID_PPV_ARGS(&m_pControl));
    A_CheckResult(hr);
    hr = m_pGraph->QueryInterface(IID_PPV_ARGS(&m_pEvent));
    A_CheckResult(hr);

    /* Connect */
    hr = ConnectFilters(pSource, pEncoder);
    A_CheckResult(hr);
    hr = ConnectFilters(pEncoder, pColorSpaceConverter);
    A_CheckResult(hr);
    hr = ConnectFilters(pColorSpaceConverter, pTransport);
    A_CheckResult(hr);

    /* Release */
    SafeRelease(&pSource);
    SafeRelease(&pEncoder);
    SafeRelease(&pColorSpaceConverter);
    SafeRelease(&pTransport);

    return S_OK;
}

Connect Filler is taken right from MSDN

HRESULT CStreamingAgent::ConnectFilters(IBaseFilter *pSrc, IBaseFilter *pDest)
{
    IPin *pOut = NULL;

    // Find an output pin on the first filter.
    HRESULT hr = FindUnconnectedPin(pSrc, PINDIR_OUTPUT, &pOut);
    if (SUCCEEDED(hr))
    {
        hr = ConnectOutputPinToFilter(pDest, pOut);
        pOut->Release();
    }
    return hr;
}

ConnectOutputPinToFilter is modified, but mostly from MSDN

HRESULT CStreamingAgent::ConnectOutputPinToFilter(IBaseFilter *pDest,IPin *pOut)
{
    IPin *pIn = NULL;

    // Find an input pin on the downstream filter.
    HRESULT hr = FindUnconnectedPin(pDest, PINDIR_INPUT, &pIn);
    if (SUCCEEDED(hr))
    {
        // Try to connect them.
        hr = m_pGraph->ConnectDirect(pOut, pIn, NULL);
        pIn->Release();
    }
    return hr;
}

In ConnectOutputPinToFilter I have inspected the MajorType and Subtype of each pin, and they match.
My Custom output filter is hard coded to output RGB32 1920x1080 24fp Init filter is a wrapper around cocreate with some error checking and an addref

#define A_CheckResult(p) {if ((FAILED(p))) return(p);}
KevinA
  • 619
  • 6
  • 25
  • You should check what input formats `x264vfw` accepts. RGB is not a typical input for H.264 encoder. Some encoders convert from such formats internally, but others require that you take care of it. Also, `x264vfw` is available in source, so you can check what's expected there. – Roman R. Feb 03 '15 at 14:43
  • Or, another reason (`x264vfw` source suggests that RGB might be accepted) that input format is not quite valid. Still accepted by some filters (LEAD) and rejected by other. – Roman R. Feb 03 '15 at 14:54
  • x264vfw looks like it takes RGB32 and RGB24 as an input source and converts it internally to NV12. Also, they connect in graph edit. – KevinA Feb 03 '15 at 15:04

1 Answers1

1

x264vfw is not a standard filter. Old VFW (Video for Windows) codecs are wrapped and all share the same CLSID. You need to look it up using the friendly name or moniker name. This code line is not applicable:

hr = InitFilter(x264EncodeGUID, &pEncoder);

Instructions here: Choosing a Compression Filter

See also: Encoding with DirectShow filters

Community
  • 1
  • 1
KevinA
  • 619
  • 6
  • 25