GmfBridge не соединяет фильтр приемника с исходным фильтром - PullRequest
1 голос
/ 10 сентября 2011

Я пытаюсь использовать библиотеку GmfBridge для динамического изменения исходных фильтров с камеры на файл и наоборот. Все функции возвращают S_OK (ну, почти все - pMediaControlOutput-> Run () фактически возвращает S_FALSE, но в msdn сказали, что это тоже может быть в порядке), поэтому я предположил, что все в порядке, но данные не передаются другим сторона моста. Я использую GraphStudio для подключения к удаленному графику, и все, кажется, в порядке - все фильтры в обоих графиках подключены, как и должно быть. Но во время игры я получаю следующие сообщения в файле журнала моста:

0:  Started 2011-09-10 15:58:38
0:  Buffer minimum 100
0:  Added stream 1: 畡楤o, Decompressed Only, Discard mode
1:  Sink 0x7ae0ca8 has 1 pins
1:  Sink filter 0x7ae0cf8 in graph 0x193bf0
2:  Source 0x7ae1030 has 1 pins
2:  Source filter 0x7ae1080 in graph 0x194c18
14: ReceiveConnection Aware: false
14: Bridging 0x194c18 to 0x193bf0
14: Pin 0x7ae3438 disconnect
25: Source 0x7ae1030 pause from 0
25: Source pin 0x7ae3618 active
2234: Pin 0x7ae3438 receive 0x721ec68
2234: Sink pin 0x7ae3438 disconnected: discarding 0x721ec68
3389: Pin 0x7ae3438 receive 0x721ec68
3389: Sink pin 0x7ae3438 disconnected: discarding 0x721ec68
3940: Pin 0x7ae3438 receive 0x721ec68
3940: Sink pin 0x7ae3438 disconnected: discarding 0x721ec68
4440: Pin 0x7ae3438 receive 0x721ec68

Итак, как вы можете видеть, левый график не связан с правым, несмотря на то, что BridgeGraphs () вернул S_OK и образец мультимедиа отбрасывается. Ниже приведен мой код. Куда я иду не так?

// Create graphs
HRESULT hr = m_graphInput.CreateInstance(CLSID_FilterGraph);
ATLASSERT( SUCCEEDED( hr ) );
hr = m_graphOutput.CreateInstance(CLSID_FilterGraph);
ATLASSERT( SUCCEEDED( hr ) );

// Get IMediaControl interfaces
hr = m_graphInput.QueryInterface( IID_IMediaControl, (void**)&pMediaControlInput );
ATLASSERT( SUCCEEDED( hr ) );
hr = m_graphOutput.QueryInterface( IID_IMediaControl, (void**)&pMediaControlOutput );
ATLASSERT( SUCCEEDED( hr ) );

// Get builder interfaces
hr = m_graphInput.QueryInterface( IID_IGraphBuilder, (void**)&pBuilderInput );
ATLASSERT( SUCCEEDED( hr ) );
hr = m_graphOutput.QueryInterface( IID_IGraphBuilder, (void**)&pBuilderOutput );
ATLASSERT( SUCCEEDED( hr ) );

// Load source filter (on sink side)
LocateFilter( SOURCE_FILTER_NAME, CLSID_LegacyAmFilterCategory, &inputDevice );
hr = m_graphInput->AddFilter( inputDevice, SOURCE_FILTER_NAME );
ATLASSERT( SUCCEEDED( hr ) );

// Load render filter (on bridge's source side)
LocateFilter( _T( "Default DirectSound Device" ), CLSID_AudioRendererCategory, &audioOutputPreview );
hr = m_graphOutput->AddFilter( audioOutputPreview,  _T( "Default DirectSound Device" ) );
ATLASSERT( SUCCEEDED( hr ) );

// Init bridge
bridge.CreateInstance( __uuidof(GMFBridgeController) );
hr = bridge->SetBufferMinimum( 100 );
ATLASSERT( SUCCEEDED( hr ) );
hr = bridge->AddStream( false, eUncompressed, false );
ATLASSERT( SUCCEEDED( hr ) );

// Add sink filter and connect to input graph
IUnknownPtr pSinkFilter;
{
   hr = bridge->InsertSinkFilter( m_graphInput, (IUnknown**)&pSinkFilter );
   ATLASSERT( SUCCEEDED( hr ) );

   // Using own functions get pins
   IPin* pInAudio = CPinController::getOutputPin( inputDevice, _T("Audio"));
   IPin* pOutAudio = CPinController::getInputPin( pSinkFilter );
   hr = pBuilderInput->Connect( pOutAudio, pInAudio );
   ATLASSERT( SUCCEEDED( hr ) );
}

// Add output filter and connect to output graph 
IUnknownPtr pFeederFilter;
{
   hr = bridge->InsertSourceFilter( pSinkFilter, m_graphOutput, &pFeederFilter );
   ATLASSERT( SUCCEEDED( hr ) );

   // Get pins
   IPin* pInAudio = CPinController::getOutputPin( pFeederFilter/*, _T("Audio")*/);
   IPin* pOutAudio = CPinController::getInputPin( audioOutputPreview );
   hr = pBuilderOutput->Connect( pInAudio, pOutAudio );
   ATLASSERT( SUCCEEDED( hr ) );
}

// Run left
hr = pMediaControlInput->Run();
ATLASSERT( SUCCEEDED( hr ) );

// Run right
hr = pMediaControlOutput->Run();
ATLASSERT( SUCCEEDED( hr ) );

hr = bridge->BridgeGraphs( m_graphOutput, m_graphInput );
ATLASSERT( SUCCEEDED( hr ) );

1 Ответ

2 голосов
/ 12 сентября 2011

Это действительно смешно, но несколько минут назад после дня поиска мы нашли ответ. Все дело было в огромной дыре в GmfBridge. Я давал неправильные интерфейсы здесь (вместо фильтров приемника и моста есть графики), потому что функции coz нужны указатели на IUnknown:

hr = bridge->BridgeGraphs( m_graphOutput, m_graphInput );

И в библиотеке GmfBridge эта ситуация не была обработана должным образом - нет "другого" бранча для обработки ошибки, и функция возвращает hr, который был установлен в begin, в S_OK:

HRESULT STDMETHODCALLTYPE BridgeGraphs( 
        /* [in] */ IUnknown *pSourceGraphSinkFilter,
        /* [in] */ IUnknown *pRenderGraphSourceFilter)
{
    HRESULT hr = S_OK;
    ...
    // if we are not given both filters, then 
    // we need do nothing
    IBridgeSinkPtr pSink = pSourceGraphSinkFilter;
    IBridgeSourcePtr pSource = pRenderGraphSourceFilter;
    if ((pSink != NULL) && (pSource != NULL))
    {
        ...
    }

    return hr;
}

Итак, как вы можете видеть, он просто говорит, что в этом нет ничего плохого, а затем он просто ничего не делает! Я думаю, что это хорошая идея, чтобы уведомить авторов библиотеки об этой ошибке. Надеюсь, эта информация кому-нибудь поможет.

...