DirectShow: построение графа фильтров (вопрос)
От: Toha_  
Дата: 13.12.05 12:50
Оценка:
Всем добрый день.

Пытаюсь открыть видео файл путем добовление желаемых фильтров в граф фильтров и дальнейшего соединения пинов первого и последнего фильтра. Но функция IGraphBuilder::Connect возвращает VFW_E_NOT_IN_GRAPH. В хелпе по DirectX SDK эта ошибка говорит о том, что в графе фильтров не достает, по крайне мере, одного фильтра. Хотя там же, в описании IGraphBuilder::Connect, говорится, что при соединение пинов, граф достраевается сам.

Вопрос: что делаю не так и как это сделать правильно.

Код:
{
  HRESULT hr;
  CComPtr<IGraphBuilder> m_comGB;
  CComPtr<IPin> m_comSourcePin, m_comNullPin;

  hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                        IID_IGraphBuilder, (void **)&m_comGB);

  if( SUCCEEDED(hr) )
  {
    BaseFilter comBF_FileSource;

    hr = m_comGB->AddSourceFilter(L"intro_s.avi", L"MP: Filter Source", &comBF_FileSource);

    if ( SUCCEEDED(hr) )
    {
      CComPtr<IEnumPins> comEnumPin;

      hr = comBF_FileSource->EnumPins(&comEnumPin);

      if ( SUCCEEDED(hr) )
      {
        ULONG cFetched;

        while ( comEnumPin->Next(1, &m_comSourcePin, &cFetched) == S_OK )
        {
          PIN_DIRECTION pd;

          m_comSourcePin->QueryDirection(&pd);

          if ( pd == PINDIR_OUTPUT )
            break;
          else
            m_comSourcePin = 0;
        }
      }
    }
    else return false;

    BaseFilter comBF_SampleGrab;

    hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
                          IID_IBaseFilter, (void**)&comBF_SampleGrab);

    if ( SUCCEEDED(hr) )
    {
      hr = m_comGB->AddFilter(comBF_FileSource, L"MP: SampleGrab");

      // Configure the Sample Grabber.
      CComPtr<ISampleGrabber> pSG;

      hr = comBF_SampleGrab->QueryInterface(IID_ISampleGrabber, (void**)&pSG);

      if ( SUCCEEDED(hr) )
      {
        AM_MEDIA_TYPE mt;
        ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
        mt.majortype = MEDIATYPE_Video;
        mt.subtype   = MEDIASUBTYPE_RGB24;
        hr = pSG->SetMediaType(&mt);

        pSG->SetOneShot(FALSE);
        pSG->SetBufferSamples(TRUE);

        m_pThisPtr.push_back(this);
        pSG->SetCallback(this, 1); // 0 = Use the SampleCB callback method.
      }
    }
    else return false;

    BaseFilter comBF_NullRender;

    hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
                          IID_IBaseFilter, (void**)&comBF_NullRender);

    if ( SUCCEEDED(hr) )
    {
      hr = m_comGB->AddFilter(comBF_FileSource, L"MP: NullRender");

      CComPtr<IEnumPins> comEnumPin;

      hr = comBF_NullRender->EnumPins(&comEnumPin);

      if ( SUCCEEDED(hr) )
      {
        ULONG cFetched;
        while ( comEnumPin->Next(1, &m_comNullPin, &cFetched) == S_OK )
        {
          PIN_DIRECTION pd;

          m_comNullPin->QueryDirection(&pd);

          if ( pd == PINDIR_INPUT )
            break;
          else
            m_comNullPin = 0;
        }
      }
    }
    else return false;

    if ( m_comSourcePin != 0 && m_comNullPin != 0 )
    {// Вот тут возвращается VFW_E_NOT_IN_GRAPH
      hr = m_comGB->Connect(m_comSourcePin, m_comNullPin);

      const char *szErr = DXGetErrorString9(hr);

      if ( FAILED(hr) )
        return false;
    }
    else return false;
  }

  return false;
}
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.