2011-11-11 2 views
1

У меня возникла странная проблема при разработке моего приложения DirectShow. Я использую Delphi 6 с библиотекой компонентов DSPACK DirectShow. Один из экземпляров IBaseFilter, похоже, не распознает контакт, который ему принадлежит, когда я пытаюсь найти контакт в фильтре, используя его свойство TPinInfo.achName (_PinInfo). (Обратите внимание, что в этом случае это IBaseFilter, созданный компонентом TSampleGrabber, который демонстрирует это странное поведение).Не удается найти PIN-код в DirectShow по имени/ID, несмотря на то, что он был ID, возвращаемым QueryPinInfo

Последовательность событий, инкапсулированных в примере кода ниже заключается в следующем:

  1. Найти первый доступный входной контакт в экземпляре IBaseFilter. В приведенном ниже коде это вывод, переданный testPinInfo().
  2. Выполнение QueryPinInfo() на возвращаемом значке, чтобы получить эту информацию. Возвращенная информация показывает, что имя_шнука является «входом».
  3. Попробуйте найти булавку с именем «Input» в том же экземпляре IBaseFilter, используя IBaseFilter.findPin().
  4. Получить NIL, указывающий, что контакт не найден с этим именем. Это, на мой взгляд, действительно странное условие (ошибка).

Кто-нибудь знает, какие условия могут вызвать этот сценарий? Я не думаю, что это проблема с повреждением памяти, потому что связанные структуры данных выглядят отлично, когда я проверяю их в отладчике. Возможно ли, что некоторые реализации IBaseFilter пренебрегают внедрением метода FindPin()?

Вот код ниже:

procedure testPinInfo(intfInputPin: IPin); 
var 
    intfTestPin: IPin; 
    pinInfo_input: TPinInfo; 
begin 
    intfTestPin := nil; 

    // Get the pin information. 
    ZeroMemory(@pinInfo_input, SizeOf(pinInfo_input)); 
    intfInputPin.QueryPinInfo(pinInfo_input); 

    // Now immediately turn around and try to find the pin in the filter that 
    // owns it, using the name found in pinInfo_input 
    pinInfo_input.pFilter.FindPin(pinInfo_input.achName, intfTestPin); 

    // >>> intfTestPin is NIL (unassigned). This is an error. 
end; 

ответ

1

Не используйте FindPin, у вас всегда есть лучшие способы сделать это. Посмотрите на несвязанный контакт желаемого направления с интересующим видом медиа. Если вы ищете специально для просмотра/захвата, у вас всегда есть возможность использовать интерфейс IKsPropertySet, чтобы однозначно идентифицировать нужные контакты.

1

У меня был подобный вопрос, это так я сделал свой собственный вариант FindPin: -

HRESULT GraphControl::FindPinByName(IBaseFilter* pFilter,LPCWSTR pName,IPin** ppPin) 
{ 
    HRESULT hr = E_FAIL; 
    IEnumPins* pEnum = NULL; 
    IPin* pPin = NULL; 
    DWORD pFetched = 0; 
    PIN_INFO pinInfo = {0}; 

    // Create a pin enumerator 
    if(FAILED(pFilter->EnumPins(&pEnum))) 
     return E_FAIL; 


    // Get the first instance 
    hr = pEnum->Next(1,&pPin,&pFetched); 

    while(hr == S_OK) 
    { 
    pPin->QueryPinInfo(&pinInfo); 
    // Compare the names 
    if (wcscmp(pName,pinInfo.achName) == 0) 
    { 
     // pin names match so use this one and exit 
     *ppPin = pPin; 
     break; 
    } 
    SAFE_RELEASE(pinInfo.pFilter); 
    SAFE_RELEASE(pPin); 

    hr = pEnum->Next(1,&pPin,&pFetched); 
    } 

    SAFE_RELEASE(pinInfo.pFilter); 
    SAFE_RELEASE(pEnum); 

    // if the pPin address is null we didnt find a pin with the wanted name 
    if(&*pPin == NULL) 
     hr = VFW_E_NOT_FOUND; 

    return hr; 
} 
0

Для FindPin вам нужен соответствующий Id, проверьте QueryId(). Для входа это обычно «В».